{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "#skip\n",
    "! [ -e /content ] && pip install -Uqq fastai  # upgrade fastai on colab"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#default_exp torch_core"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "from fastai.imports import *\n",
    "from fastai.torch_imports import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from PIL import Image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "from nbdev.showdoc import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "_all_ = ['progress_bar','master_bar']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "if torch.cuda.is_available():\n",
    "    if torch.cuda.current_device()==0:\n",
    "        def_gpu = int(os.environ.get('DEFAULT_GPU') or 0)\n",
    "        if torch.cuda.device_count()>=def_gpu: torch.cuda.set_device(def_gpu)\n",
    "    torch.backends.cudnn.benchmark = True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Torch Core\n",
    "\n",
    "> Basic pytorch functions used in the fastai library"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Arrays and show"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@delegates(plt.subplots, keep=True)\n",
    "def subplots(nrows=1, ncols=1, figsize=None, imsize=3,suptitle=None, **kwargs):\n",
    "    if figsize is None: \n",
    "        h=nrows*imsize if suptitle is None or imsize>2 else nrows*imsize+0.6 #https://github.com/matplotlib/matplotlib/issues/5355\n",
    "        figsize=(ncols*imsize, h)\n",
    "    fig,ax = plt.subplots(nrows, ncols, figsize=figsize, **kwargs)\n",
    "    if suptitle is not None: fig.suptitle(suptitle)\n",
    "    if nrows*ncols==1: ax = array([ax])\n",
    "    return fig,ax"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "_,axs = subplots()\n",
    "test_eq(axs.shape,[1])\n",
    "plt.close()\n",
    "_,axs = subplots(2,3)\n",
    "test_eq(axs.shape,[2,3])\n",
    "plt.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def _fig_bounds(x):\n",
    "    r = x//32\n",
    "    return min(5, max(1,r))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@delegates(plt.Axes.imshow, keep=True, but=['shape', 'imlim'])\n",
    "def show_image(im, ax=None, figsize=None, title=None, ctx=None, **kwargs):\n",
    "    \"Show a PIL or PyTorch image on `ax`.\"\n",
    "    # Handle pytorch axis order\n",
    "    if hasattrs(im, ('data','cpu','permute')):\n",
    "        im = im.data.cpu()\n",
    "        if im.shape[0]<5: im=im.permute(1,2,0)\n",
    "    elif not isinstance(im,np.ndarray): im=array(im)\n",
    "    # Handle 1-channel images\n",
    "    if im.shape[-1]==1: im=im[...,0]\n",
    "\n",
    "    ax = ifnone(ax,ctx)\n",
    "    if figsize is None: figsize = (_fig_bounds(im.shape[0]), _fig_bounds(im.shape[1]))\n",
    "    if ax is None: _,ax = plt.subplots(figsize=figsize)\n",
    "    ax.imshow(im, **kwargs)\n",
    "    if title is not None: ax.set_title(title)\n",
    "    ax.axis('off')\n",
    "    return ax"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`show_image` can show PIL images..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 72x72 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "im = Image.open(TEST_IMAGE_BW)\n",
    "ax = show_image(im, cmap=\"Greys\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "...and color images with standard `CHW` dim order..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 144x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "im2 = np.array(Image.open(TEST_IMAGE))\n",
    "ax = show_image(im2, figsize=(2,2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "...and color images with `HWC` dim order..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAH4AAABZCAYAAAD4ipAGAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/d3fzzAAAACXBIWXMAAAsTAAALEwEAmpwYAABN20lEQVR4nO392Y+uWXbeB/72+E7fFBEnIs6Qc40sFlkkJVKUSJqUadKWLRke0AakBtx3gv+Pvuqb/jcafdFo9IAWWm5rJC1ZIkWWSJFVZFVlVg5niohvfOc99cX+MtltQEkg68KAq95CAlknAwfxfevde631rOd5lkgp8ZPnx++R/0v/Aj95/pd5fhL4H9PnJ4H/MX1+Evgf0+cngf8xfX4S+B/TR3/ef/zn/+xfp2k6MbR7mtUj9qcBJWFZGd565z3uH14zDANSSBbLNVoJnA+cTkfcNGJsTVmWXFysKMqCvhv54z/+I/aHLdZalDC8//6f80/+8f+H97/3PaSQFGWDUYpFXfPk9pb/8u/9b/nWL/wiL198whwl7771jMuLC4QQnE4HZjeilKEsSwBSioQQ6fsBpSR93yNSoFluKEvLYtFgbcnLly8hSSCyfXhJTIK6tNSLC5arJVorhJDs91vKssK5GRD0o6cuLP35cxtrGMeRh4c7yrKhLCx13XB//4qrq2vatgMk+/2Bi4sL6rpguVoQQmC33XE4HrC2QAow2vLRJx/R1EuOxx2Xl48YhoEkFFJqju0R72aaZkFdL0hhJvhAURr2+yPHw4m6LtHa8Prunr//9/9b8YUCP88zXXfCaEMEri7WdF2HLSyQaOqGcZgAyTT2BKWxRcmyaSguL1FGUpYVKcE4ToTgeO+9LzGMT9BKUpQlX/361/jWz/0S//f/2/+Ff/qP/iHeTUhR0g09dw9bfvef/CMur664uNxweXnDctUgBLx8+RJjDcvlGjePzPNIVdWEAEpCXZUkIbFFhUgBIRXWFlhrOez3SKkASYqJ9eYaYw1VVVGWJTEGQvCklDBa0XUdAoUQoERCKsEwTEiRkGpBUVTc3Dyma3tijPR9R10v2O4eWK8umaaRN954QtPUCCGY55n9fsc0OZaLJd57pmlGKs2Tx0/YbvPLJqXEGA1CIKXgoinox4RRiod9i5GBZV1SljVNPdN3A94HvPd4N3zuif/cq15pwcXmksVyzcPDPUM/MDhFwhJToq5rUvJIKbBFgVQSKSWL1YLVZkVZVnRdxzhMTNPM0LcUVvH0yRPWmw1NU7NoGt56601+87f+U3711/8mgUCKnuAj7dDzwQ8+4Hf/yT/i0aNrLq82xBh52N4jhECQGIeBql5QFCXzNKC1Rsj8Ap56R99PvP/xPSkJqqpiGAaGcSKGSAgztqhYrtZcXl5SVRUxBpybPwuQkAopJBBQWlGWBTFG6qYEmRBS40NEa0XTNEgpAUFZljTNAh9misJycbnCFpp+aDkcDoBGKQuAtSVlVeFDpKprmqZmuVrSLFYgBAIYxw5TFCyXa2bnuFhWvPPmM54+e8I4dnR9x2JZkRCEmFitLj438J974pumxvVHfJK8+ewNfAgUZaJZlDjnKJqGsioRGJq6pqwsQki89/T9QAyRlCQ+BpQ2GFvz+v6e91YrmqbG+wA4UpJ87atfZrX8u/Rdy7d/719jrCYhOA0jP/izP+f5xx9SlhVt16GkpF43uGkkIRj6kaapKYqCrjshpcJ7QZg6PvrkY07twOVSMfR7pnFivbli9g5SwFqFtRYpJc5NCCFJCWJMSKlRUrJ4tCQEzzx7Yox471kuGpq6YnIg8YzDxGKxwHuHlIqUBOvVktPphDaavh84Hk+QQJDQRhFjwGjNoeuxxuDnkVOcKauKw+FASicWyzV+HtHaMM8jdb3ktlmglSKmwPZhi5sj1hQIIVmvLR99/Bz5l1Rvnxv4GANz1Dg3IZWkPR3OubQmBMfsZhaLJc45hITdbkdKAq0Mxlqc90gJxlqGfmSeJmoDfd+xXC4JIWCMRcmcT996603+9n/+X/HRDz9g+3BPJOJiQIrE//X//H/iv/57/y1vv/seAsH99gGFJwrDZrNmf+qpS01dL3j+8Uf88P3v8+++/Yd89P3vM7Yt/4NRWFuy3mx49s67vPHee/z0z/4cWucACJFQSuFmjxAS5/JNloC2bVksligVEELhvUcIgdYGNw9MfkYqRYiRpqmRUlLVFUpJhBDcP9whUEzzxHq9JiWd04hRJJFri5RAaY13jqouuHp0w+tXz9FGE2IEAs2i4erqkhAC+/2R7W6LURptJMY2TF5TmsDtzSM+ef76iwfe+4g2krKsczFB4mKzoapz3nbzTIyBcRhxLmC0YZo9Xk6MY09KUDc1UkjKwhDcTLO5ghSRQrBc5vwWpCDESFFWvPvul/jZn/sF/tE//AckApMfSDHxO7/zOzTLhv/iv/l7XN8+RWtDqTSqqCAlvPe8evnA8w+/xx///u/znW//Pm5yCKFICOQo6FPP7uHAi49f8u1/9a/5g3/5L/ny17/O13/6mzx96x2MsaQkUEoyjg6tDcZI9vsOIQSr1Yq+H84pIaKUZrFsKMqC43GPUvKzmyelRNseOLUtVVXj5on1+oIQPTEk+r6jLPNN0zQ1x2NHVTZMYqRrTxgjubm+5YMPfsDV1Q2zm7i+ucH7yAcfvE9MiaqscM5hbcPDbk+QFcZYNusVXT99buDF5w1p/uRP/jTFGBFwvlJblBT4GElJYE0BCJQyFIUhAQ/3rxDRkaRltVqRgsN7R1EtEVKwfdjS1BWLxZKqqRBCME0TMQamyRGC4N9++w/4P/4f/vdsd3sigrookSKxrCy/9R//Nv/l3/3fsbm4ZBp7xtGz3d7x4off43t/9Ifcv3iBHyfc7CBBAqTWkBJziJAgaEOMAmkMi6bh6vqKd7/6FX7uF/8aj26esFzWOOcJwVMUBeM4IRAslg3jOOJmjzGWkBLWKgQ5NRRFgVKKaRo5nU6M44iSBmMMiEDf9yhZgIi0pw7vZ1brNYUtGaeZeRpxfkZKRfABKcH7RNsduL6+ZRwmdvsdQoDRGkQuTqUUlGVN1x6Z3chqfUXwgd/4m7/yxar64+FACBEhoKorun7A2hpjLHVVkMhFjw+JkBLDOFKVBXM/UNZLpJI4DwiJlAKlC7quQ2sJvSYiuLhYnfPip1en45133uHJs2e8vntNSoKgJEkI5lnxP/7Tfw5K81/8b/4u7fYV3/mTP+HPvv1vONzfMfUTx3HEO4+SAq00xITSksIUaK2wxiK0RCrDFAXzNPHq1R1dO/DhD97nm9/6Fr/0q7/GxdUVKSWUkhSFJcYIkIvI+YQQ0FQWpTRCCPL5STw83DOOI0VRslqtkFLh3ExKGiklKQX6rkUmT6EFKSVOXU/X97h5pK5KYpI4YF3nDunFi8jHH3+IUhZBYLO+xEXFPA7MYaK0FUjBOM+QBPv9Hq3/vTH/ywMvVEkIgUVlubxYMw4D8zyhZGK3awGBtYaIxgfHMPRsVhu6YcSqGnSBCBI/DTy8/oTVxRPefvsdpJIkBEkoYoSqqmjblnnO12tRGn7rP/5b/OAH77PbbhmnCSElMSVSDPzB7/4O/rAn+JmHF8/pu57ZB7pxYpxdvgaNwcmAUQbpI07kl2EeBrT1KBO4WDQkaRiDIDjP9mHPH/yr3yPEyG/97b/DYtGQUsz5VynaNn9mYzSzmxAyEeNIOqeaaZrouly/KCXPf+7QOvfhUkoOhz3L1ZqyKJBSIqTk1PaU1tL1HSl5mrpgubpgnHq2ux0hRuqqQSpFjAnvZ6wp8UoxDIpSaI6HHX3fYk3FerPBu/GLB34YZ5QIkDRSKaw1aK2o6hK/d6QkmOZA252oFyuausYUFbe3T3FRoqREWk9drehVJAnFD5+/QGnF09snSOFxbsZayzhObLcPXKxXKKn4+je+xdO33ma/3+KCRyMhSi6XG66akvf/9E/wMdJPM+M0MTtPTAEpFFLKXBCd2zAhLVKAEAKlBbls98zjgFYzq2aBMgInNN4F/vgP/i1GK/7af/DruZ9WkhgTQz8hlaIoCqxR58pfQQJpDHVdU5UFx1MGbYqiJMaImz2JOd+cVQ2A8y7fKNqglcBWJVVd4dxEXVX0Q8/r13ekBEVRUFc1D9s7FosLvJ+Z3YQUAnxPXazxk6WqFhitGPojPnw+z+JzA19ana9GpQjBI6TCz579bosQgmbRkFDUdcNi0SClwBhJSApcoD3c0ZQFbgpUiwvafmCaRp5d3LJZ1RijmKaJ/W6PtZarqwsUKefL0vLrv/43+fAHf87Q9liluFkvuGgqtrsDzntCSrTjhI8RIyRKG5RUpBQZnEM4iNogK0MkMvsRayzWKESUhAApRsKxpV6CloqqrklS8N1/+8dsNhe8942fZbNZUZSaGOF4arFlSVVaYgzEmLsfgcAYg/cGJTXGaKoq1wcperSxTNOI0QatNbNzhAjOJaZxousGlBJYa9kdjtzd3bFaLmmaJf3QQUys15e0XUdZLhB4pAgsa8sw9GitWa02jOPA0B1Zr3+EPn63vePq0Q3eTWziMuczGamLJVKJz64xZQzOzXRdx6OrKxLghxatLC93E8M08+6zmkeXK64v15RVfrNPpx7nAlIpjDZUZYkbW5zzVFbz9a9/g69/46f5k2//Ic8u1qzKivv9kZQCEsHsAy6EfKVKQfARpQRaSpRWFEqjpaSbRi7Xa2KIDG4mIPAxsDA5dyujCCGhCIztAVs5jFrz3T/8PZZXV6w3S4SAotA0sWaeZpTIOTTEiCBX+FJKlNIYm5HN+Zxzc8vo0KbMuTclIDL7SNcN1IXCaIU2BbNzxJBYLtcoY0FpinoFKRL7gao2HPd3rDeXDP1IYWsQEVtWHE8Ddd0QY+Dy8kcIvAo9Mk6UdolUGbUahxnnA9MYqK2krkqm2RH8DCnlXr9uMFphyxrHyGZVs1zWGKPx3nM47Ag+IqQGYfKX5GYSFls1jLOjKCyPHl3xN/76rxAe7gjTxKEfGd2MVQIXYfCBGBNKcu40wEoFMSISoDVKWwSC19s9dbOAlCgNaK1RQpCkJimTK2TySzOeWsauI/qB7uEVhf2ZXMBJidECa/JpL4oCe66hnMvgjtYZEEop9/pCgdElwXseToHaBObhgJQ6t2H9HVYYCqOJPiGSJEZHCgM+emJRMU6BaRqJSYCy2CIfHKUMicB+t6WuV0xzZLNeslot0fpzQ/v5gV9fv4WtS9T5qrc2B0kKwaqpqasSqSRCZIizritiiiipKBcVWkue1SVSwjiMtKcTtihRyuLmnsPuNbZcUFpD3+6pFytiWSFVQUo9bu55eP4xwzhy6obz6UpMUeBjIgIxgULhY0CIyOwmrDIoIXAhImUGYrQtEDGitGL2AVNUzFIjpEQmiUcilc4zBKWJIXDaHvjDf/5PuXr8lHe+/FUQgmkYEEKwWK3PwA9Iqc6FmkLBGbbVKK3Z7ntWVYGSirrUSAJSWYQQHE8nkIKqbnDHB5ASUa7RynDstnTtC96sG0qjECERk0CaghTWdIdXXF1cslqvMLrg1B4xMrJoKoSQfPzJJ3zzm1/9gideW+5ffULZrJmGE1fXtyASiEhRGKS2CJEQJGxRYq3FWoO1FiHIRcg84b1HSk1VLwnBQUpYW1HXEUREENjfv0Jqg9YFCcE4OX73v/8H/Jt/8T+ybwdG53DeUWiFFIKYIKaE1hofA1pljLLQhsLa3MrJ8ylWmkfrOvfYPjLOjjkExDxjjQYlSSEgrUGrjM3rsjynrJH/6R/8P0m//Z9ycfuEuq7x85iBp3Ofn1JiHEeElGglSDFDskpKNnWBkAKlFOtC0B47EOADlNZg1RJrCszlDdPksEWBD4nV5hJjDVIk3DyhRKK0AlsZxnZmUTfM88zr16+QUrDZbBiGgY8/+pAEzLP74ic+BEd3PFA3G1KSGYIkX2vjOOTRqpSs1us8HBGCGCNde2KeZ7S22MJSlCXOJ3zwuMkR44zSBdoUCBFRUnD7xjtEJOM0EELg+9/9Dv/qd36H+8OROYQzbEl+oUIkQq5qAUH+M4SAEInzzLJU1EXB7eWGyiiePb7GGMu+G3n1cCDESKk1i9pSaInRColDy/y5hcyAVF0uCGPHt//xP+Tq7S/x5le+ynJzyTB5bGFw80xVN3gfECRSzL0/5O/CGAWkMxo48tHHz1mtlhRlTQozp5cf0pcVt2+9i/AwTjMxJo7tieur63NtYfFuoqobZjfj557VeolSir6fmCfPHB0CaJoFUhqG8fOnc39p4J+982WEVEAEBFVdEkJis7k4p4D5jHI5QOS5dZIUxQIh82gXPCEJSiOxTcPhBIoEKQd0njwhBIbxhDWWYRj53f/hv2e7P5GSQJy/xBgjzksKo88Bzyc/xEQkoqVCS8GqKnn39pKnt9eU1hCiYDi1dEKhq4bbqzXRTxAiIXrakyMKgZtmrDUUhaWbW4yyDGNCa0Xatrz//Y/44//pX7HcbCibBddvvMHF9TVSaea+pagqLm9usWWNUJqmbtBGfTa42u0PrFYXGA1lYYlBUSw3LC4ukVLR9SNKSsrS8OjqGlto5nkm+ImiKDC2YLs95LZU5RmKVpJgJFW1xE0D49SDkFRV9cUDf3V5RUwRYwwpRcZxRAqBMorTcUdKIJWiKmuUtmitqaqK3fYBbQxCSNq2RZ0xAB80KuWxK0lTlDnIUmmk0rTdQOs9u7tXfPj+95l9ACkQSUICFwJSCmTIEHKhNQKBEKBlhmUro/nm209YVQXt4cDrwSGNxWhNSuCHgHMT0TvqqkIiiEITU8ILQ3QgS0vQhhA8vh9JIVJVZYZ76Rm6EW0NL374AUJKxnGCqWNRl2xubnj21a/x1te+gRC36NlQ1RUheIw2SAlNZQgxoU3B1ZM3kUqx6yOyWJFczzyONE2DEBrw+Lll0VSfdQNlWbDbbnEhYrTE2oLtwx2LRck8OYyVDEP3xQO/3d0RQsyFixAoqSnKEiFEhm61IUaPtQXz7NFGU5ZVJg8gUFIxz56+P3B5eUUI+ZRqJQhuJEaTkb8Y83AnCeZp5MWHH9K2LTHlAg4EIUFKiRgjc0pIIYlKEs84xboseLxZcbtZEmfH635kcoF2mvNo1Rq0rUAaEorRzwynjsIWeTycIvoMv4phQhrDFCPjNGGVhDHnzXK2pJRomhpERhOnrqU/bDnJxPHuNXcfvM+L7/4pX/vlX+Wdb3wLpRRGa5QyeB+BiBE5RfVeIbxnWUhkaTmeHETohhnvW5xz1HWNKQrGYSR4T11btIxIXTDMnraPFNaipIHkOR17NpePvnjg62qFVIoUA0kI9scWoRPedZTFhpg8pEg/DLmVmTVlGdDa5L9ca+qqYOhOtKcD6/UKbSw+CnwUuHlASYmxltNxh5EKJzT3zz/ETxMhxc8qd8iDkBDTGQLNhIMYE5dNxTefPOLRxZJ2dBw7xxQCg3OEmMBNiJioTU0cJ4KQzOfUkZhRUuFiRMiIUobJexQwu5kYYRp76qrC+8AUAn6emIYebUtm79AxEnzAi8Q8jiRl+Pj9j+jbf8DDq9d8/a/8EjdPn1LX9flzROZ5RgpJEAHnElYlUhIsm4KULOM4En2isCV1XaO1YRx2ICJVXVGW+RYJIbKsEiHVzD5Q1iuO3QPHw/5HCHxd473DpRmBJvgBq2tKU1OUBTEkgoiMvaMqNfvjiarKuag9toSYKMqKy8sLQopYW6GNQLiIMJEYPEJqum7gcDhgrcVPgdN+i/OBFBNCSYQU5xcgvwFCCEDktqqyfPXxFavlgrt9x4tDi4sJozSj9wgpKRDcnY5cmpJls6QbJ4Q2aJ0IQuSxrTIkkVNKSAkZIoUtGMaRECM+ZNAoCUFC0k0zYpxxbqIpSmxR0B22KFHh5YRPgu39ju5f/A6vP3yfn/213+Ddn/oZlFYADENP0yyprSZqhQ8ZAgdJShKEo2oWpJgwxjCNA9M8U1cFMQRCUnjn8W6ksAWHfmJRFbRtxBQNMH/xwOdiq6SqKqTQwCUCWK0ykhVjZJ5GKgNdP+WT41zOQX6LMjYzQaTET7nXdy4wjtNnnLuu75imkcViRdceads9QoiMD4QAnIMeI4lcuEMinZks710uWZUlL3YnXuxPHIaRprA4lXAxYlWidY59P5DMCS0gREFKAaUtxuQ6QarMb1NAmEbUmX2jqoqjd0zDgFEaVRQQPMpohr5nGDp08iRjOYwz1liWFUTn8UoxTyeOxz9j7if6w5F3v/mzlIsVZVmfW8JAjJ6x21NYi6nW57ZYE0JgnBzGWHa7B2KIFIuaaRpxzjFN/gzUJNaLAhEDZZFHzV3XfvHApwjPX3zMZr1mc3GJJCG1IkSPiIJhGHj+w+9yUUtu3/sWPkmGwVPXJUVRIACEzH21zoVcVVfAiClqgpsRQqGVohtP9N0JJRL1MhMqhRAEIHzazomMpysp8TGyLgs2VcHrw4ntMHMcZ1yI+JgQCqQUCCERpqBeaFzwHPsRXVYkzkMkY4nBQ8odiCAhU0J5h3czIiVqWzAjiCGAd2hr8d4zTAPD0BOmAW0Ms4/cn44kAYvFChcLrFJsDyfEDz9kmga605H3fv6v8Oj6hjCPVM2COQia5RU+BHyIdLsdQgiMsdgzQ2ieZ2KKDMOYC1UtSUnjg+d7H77i+tE1lZXMPtD3e8Lcf/HAu3miSCMprXGzoyosMbiMr0vJPE8Zg1ZNvn7PkGWMkaZZ0HUdCEUIDqUtMeQvr64bvJvxfso1Qt/Sde25iLSsLq8ptOI0BWIMuXuQCu8zKBFjQkvJRWU59QMPg+c4zYwuMLr8BdU+D0aSMdR1A26iPewxymBDQAiJUSqDNDHmOiIFFInj6URdFERASUFT1znNKEUIMedcY2i7EyElHroBLQRCW3wyVFFRCY2OkckHInDqBtLrB8rvfofLJ09YrdYoKej6ASklEZURQCEoy4IQIofDnrLMFK6qqtisL3La8Y4kAj4okpu4WK1Ic4+uFmAlWlb0Z9zjCwVeFhtqpVA68748mrKsccOJ/WGLkIbL66ckEl0/IaRg0ZTMs8dYw7zLeHJMklIXVGWe23ddCzEXhm17ZLu9p64qFs2a/bFlnDxWa6TMFW4i5RdLiHN+hxAiIQQOQ6SdIzFl+pY1htIaZEpMs6OoFviUaLuOkCJziqgkkDFlHMC5TCfxGbyZxsyhSzHk2YKQpPZEUZQkBEoaqrIiApv1BdE5vJ/pZ0c/jNRlgTaGql7k3zcFkpD084yeNIeHBz76zp9w9eQZhRKYZoWyNd0EjYIYZuqmpus6iiJ3SNYWaGUYpwGlcufknSfFEYFhs7nAzQPOR+ZpQCmLKcrPDfzncjH7/shHn7zg1es7+r5nCEX+Z5rpRoctKlarS1wUnI5Hgo845xiHjhgj1lqcm1gtl0DicNhzf3/HPI25b/YeayRXl1es15ecuplx8phqQXnum/3/7M2NKf9/KSWSlPnv0TF5x3QOYgyR0XukloQU2e739OMIpsCFRDd0lIVBxkDwc77aSfRdS9v3BB84tke6viPOjmEYmPuWOI+o5EnesVg0XD9+xqPbpzy+fsLFcklKiWGc0GQChg8JHxJScCZjJoZ+4MUH77O7e40qCoy1BDdjVUTJACLPE/quw/ucww+7O3bb11hboFQWcIzzgC0UZdmQS93ENA5IqRj7E276Ea76P/3Od7DacHv7mKpsQPbEaSD4wGKxQWuD0obgRhbLBYvFMnMfUoZ1ldbE4Nnutjjn0FJSaAnRE30ep9ZVjVQlL1/fcbc9kcLMOHQU8jxezTQ5OE8zP6UIxpToZ0+pJc572n4mpES0BiEFzkfWRUkSgn4eM1kjeDaLJVVRZB6g1hTG4ENgnkckoJVi27Wk4CmMYXADhICigtlB8BglCWNBtb7gzXfe5fSwYLFbcNf29OOAKCrKZkkIESsFSgqiTKAycDOMjrHP7WCMiWnsqeolzsXMpTt/xlwMe07HEzFFVpsMptXNknmaOJ12Z9FFibILikrTtQdsYRnGHwGr/5mvfzUHLyaQiroytN3A5eXlmV6sKMuS5epnCDFXqH1/LnhCoGkWGZNO0NQNEGiPB2JM1E0DSPph4tS23O1Hnt/3mNTy0SevkUqjzgOgrGz5C6xeiBz43TRzIy2EQEoBHxMhhDygiAkh4DSO7I9HYnCURcE0WS5WawpbcGxbSq1RErphgOiRQp6BIhjmCS01wzQSg6epGlKMRO/xY89ifYGta7S8wRQlT/YHvvPhDzlOE0+lRGRoE11Y0jDhUsSHhDaGxXrJ0LcEWbE9TizmxNObK4zRnNoW5wJlpVHacPv0TaTM/IcUPT5EvJtZLpfMczjfoPHMBTDE4FHKf/HA101NWWaivtYSWxgujEYpeSYfJvq+ZZ5mxqHH+QhCsVgsskhBZGi17090+wPGmIxhNw2IxDQ6psmhjeHmoibNJ45HhYugmxVa3ucqm6ya+ZTNKrUgpEg3e3otqYxCTpkL7LxHpkRhNM4H+nGi63sKLUkh1xU+ONycqU/H9kgMHisk+9MRKQQeCDHgB5cLSxKnmGldhVRM00xZNUQ3I4TMZImy5Hp9wXf5kGPX4+c5n/aiwqc8yo7ThCwLVpeXrK8es1heZJ5d9CiREUEpBX17IoSRcRR0g2PZVOfABwQRqwtMU1NWJV03IJCE6OnaUxZ7rC6ZpldfPPDLZU0MESES3s3M08Ds3GeCgqo8FzzKcHP7mN1uh/cRpVQel/qJeRyYxp55dtTNCqU04zQiRR5eaFsQUqIsNPieRW1YrWpad031/GOOkydGn2lOKeYTd+YE+BDYj46nC4uRAnemUkUpISUm59gd9oTgkLZEAEpJpFA47860cWj7nhRi7gjOFDMhBClGfAxYpRHAqe+wUlAUluBngptJMfMUwiBYFIa6sEQEPiVMghjB2IJxdiSRa46LmxvqJnPilYS3n2RGb4iJFHOBZq1F2aw26seJzXpNiolpGpldpCqrTMd2ju1uS1lqtFYYu+B0PCCl+eKB79r2My2YUploUNcFSmm0NoSYJ2LD2KNUJht2XQcpMAwnOPedUhrqRYHShrY9obXN+jQpcPNIcBP7h9dcXj9lv9uz2WzYbR+Q2kJqz1Ks/DvFT0efAlyC3gU6F6mMZgqJmGJm4wLjONL1HUblNkkAs/P4GKhNneFWlb+Cfp7wIacrIXI/HVPCnF+iGCXSJtphoK4qhBQIJXNvH/Ok0UiotOI4DZltu9lkNDKEXEWniJaCZ+++R9MsSAm6zp8p2zN1kaHaEAUXq4sswPQzUZrMLipKpNZMk8f5hJt79ocjSkm6fqKqShZVyTRlltTnPZ9b1c8uIoRB6YJh9HRdnvFqbWm7Hu9yHvHOc2pb6mZBURgEkfZ4wM0OISVlVVHXC/q+I0Y4nY7MbmYYRu7v73j+/KMz7uzPsivJcrXBLNbUViPIzBvIuT0lEPIv2rrtMFMqQXHmCxiZCZDjnIUaeTQEzge6oWe337Nvj1Q2X68JgZQSHyIhJnyIWW4dQ+7fU641XIgMztPNjjkJTL1ESEl3OjJNmYFbFRm/V0pQlCVSCqZ5yjMJrXj2ztu88/Wfyuxao9lcXCJkpm8LKZjnKZNayhIpNRBQac6s4PPfE2LKs44A1mSa9mKx4PHjJwzDyDxP+Qb9nOcvmccH2vZEVdUMfQdEqmpBCH0+hVqCgOVqSYqJ4B1SCMZxoGkWhChpypz/uq5DCoE1CjBIadg+PCAQ9P3AZnOBlJpFkwcSVVlwcX2Dip5++iGTGzIjNmSipE4KqxVBityihciiUKg5Ucj8qozzjABKo7LMKiXEWUZMiATvWFVZ+57TzxmLj/GsxgUlcuvoQkQLSakVioQQim5yhHFkOh1RwSONZVkWpBDyz2nFNE5MfUdhLRebFd/6lV9FW0PXns4wsclDrZSL0WkcEWRcQap8aLzzGeMX5G7EaoZhxM1THkkrsBq69sj9/StCSKwvbr944EXylNUCRGR2HmMMMQna457VcpVHqiGSUq4sExFJRGlNN0zU9YJmsWS/30GCqq6Z54lK50lXXVcgFJdXZ8Jg06C1Zrlc4OaJerXB6LNi5JMXHNOIO8OaQUm0zKWfC4FuCujKsKgKUsz9v4+5FimtISTQQqClJp1vDyUExMCysExNrtgn50hCEGLAao1S6rMbozSaVV1xvdlQlQXRTQx9zzR2KJeHKherFeb1HSkltJb0/UxwI9JEfuaXfoOv/fwvkGJOgcv1+kzSCGdYNnPlhRKM43g2TEjYc9uXu438s0pEdFUQQ0SbAq0t93cPpJRrkGn6Eebx3k+EUFFWBY9vHyOkYnJZ1VGWJaSZ9nRkmmd8iDRnbbeKkcl5lotlJgQISdeduLAFRVHTdUeEkJRVyeQi0+xIJJxzzMNAVVZYa1hvLjgAs7Zcrha5kh9nnPeUJudtJSHIDOFOPk/QSi0+m/2rMwlSQxZYKMsYEi92O/aHHasio3xKZObOICU+BFzIs3Yl5Rk9hGF2vDqduG97mkPL07feYVEvqLVif/eKJnpUWZNSwhZFLnCnjmUh+eXf/E1+8Td+k9Vqw/39KxIBJcUZ/uaswRcsViumaSKlxDTNaK2z9g6JEJp59jg3URYlzs95+liUnI5dbpPrBS92I8Z8vmjycwN/ffuE0+HANEqUSlgrqMv8hXs/MbSnM+HRUJbFWVasKMoKM44MY5eBHKlQQrDfZ8BhtVrTtqf874ua4C9orSGGQP/qfaguuby65qOPP+F0OnB1/ZiurPDpIwQto3PMIWaARwrUud2MEXrnaYoKrbKjheBT1EfgU0TjWTZrvHccT3vmQaKExGhNVZZURuNyBssaPwT9OGbatXPcXD1idzzQ7rasbt9CWiiUoWwWOEQWnohckYiUWJWaX/xP/g4/9xu/zcXlVa5NhEQpk0fS/ZFHjy5IMTGfkUelFO5cP/V9j5QjdbVAKkFVWYxRKJVZQ0VhcoqYJ7TW6KLgVhl0/BECX1U10TvabsSHmWZxRfCOeR5xbs4t2mKDVJkYUZX12ZNGsVqtmWeHD/na6tpjBkUmR0KzaBYcjntIgdVqhfeBeZq4fe+bOO+YppknT265uX7E61f3vAR09UCdQPQjs3e4M7Gx0BKrFd2cZ9pZPJgIMWCUwp5BqJTg+tEjVFESXGCaZ/bHHaXJgxujDY2WFKoAkXt4IwVT1l/hYyaM2qLkN3/tt1hf3+Kngfe//+dMQ0e12bBerVjUNUoAfuIrP/ctfvG3/jOqekFZlmddfEFKMzF6LjYLpBAM3jM7R6EFZWkJ80gSiqqqmaaJl6+es16tsUVJ254QQlJVDXVds9ttEUiQiboqWdaGebSfG/i/BKsfsWVDP7SE4Ll7/RLnRoZhQAiN1JYQAyQoiobRQVnlPH48HpgnzzTO7HY7JucxRclmc4n3jn7oqas6EyjdxMXFBmM1ZV3RNEumaWSzvmSxWJFkyTj0SFsShKIPkSgVU0qMPiClwiqFTLkz72b/FwxcQcbKRWRR16wWa4Zx5O5w4uLyGpdytT/HhJSZv2aVpFKKWmsKrbHyXMvILOT45b/+66gnX+IH90c+fvGC64sronc0iwZ75icWRrHcLPnlv/1fU9aLcy2UyScxZDBq6DpiAO8Dzkf8PJ2nhGRuwzznXt8UbDYX+BA4HvaklCVb49gyjtn3RirBctnQtTtijLx4+eKLn3jnPILIzc0Np/0WgLbrMaZgnCba4wFT1mzWa5zLOrsUI/v9IdOKpCQKyePHN/mNBIZhZH/Y8vAwsVqv86RrGpjnbGcyzxPt6cRyuaZrO3zwiOR46+ljZu8Yppm3liumaeBwPNHNMzE6FkUGMEQITC6wsmCkymqUGCiNou07njy6oV4vePnyNZ4MJcuY2T5KSrTM93wmceQUpRY1Lw5H3nr8jL/xc7/I5p0v8cNdz3tf/Wne3Bie/7tvs39YoLVi6luSczRlwZd//hd48tbbgOQ0OTba0rUHnHdopWgPW0KILJYrSh1JImK0xXmHqUqKyjLMiY9e3fP4akVVGaK1+UWdJkIM3N/fMY0T1zdXZ/6D4v7hkP1zvmjgU5jphg4pNaUxJKHo50AMYGxJvTj31jExDAPBe8Yze+V0ym/ezeNnGQHzWQKtreHy6pa6bhFCMbsZrfJV3LV7UopUVcPxeERIzbEbefb0BilumIXk0dUjYgi8ePGciIC2Yxw65hCotMy3QMp4thCZk0eMVKbgOAx8/NEPuNlcsNDwcBxorD1zCBJlUWC1QgqDPEusSqUpvWcIkZ/66td498tf409f9VyvI0vjUbLiO9/9I548viX6iLYGJQVVs+C9n/4mIBiHnqYwSCkYp+l8EylWl9coKZmmma49cDweuQ6RsqmJAUICJSXLuiI4TxKQksTY4tz6TQgkRSk5HTtskbkHUiiOPwoDZ/vwimkOLJfLfE0lxXK1IoZEezoSvKNcXmFsQVWVjEO2DDHWsFpd0HctU7BY6Xm921KajNOf2o7DqePJ1QVNnftoqSRDrxDC0rYdXX9iuWz4+uIdxnFinifeeOMd2tORh/s7rq9viLxGCEEnBT56aqM5zSGj+iJX9Ak4jiM3q4rGKL7z4fuMY89b149ZSs22SxRlTRSSy9JSpOwAYsnFlpWChS1YrzdY5zi8/pj/8Od/CW8Mx1PL7/zD/wd+nlhXJS441quKxlqapuLR0zdQKhMsELkOUuovvvK6zpYqxlqUljTLTM6QUrLdHVg2DfM8YM4eQTEFDsc9j29v8S4iJNRVwzD0jENPP/RYrbKxVPz8efxfwrKt0YWkrGqM1dmkYByxpqBqVshiQWkttQWtBCfnUUhk9BSFoRsE09AiC4OUkmPXoXFoEherJTElpNIUEo7HHUVRA4K6EbRdy2KxoOt62nak63qsVYQIc0i89e6XEKZiaA+07ZF4eMBmSymEEPTOUxrDMM2MzvPy0LGpShgS33/xgg9ev+b26ooUIguhWNQNF+tLyhTo+47KGKKbUGGmKCuWN28gtOGhPfF7v/cv2B0O7A573NixbmpsUUA/Uj9+RlV8m/WjK8TZDMGezRdjyMxepQuMzUqdlBIpBepmkbuaKY9+LzYbhBCM00xZGE6nPVVZsV7UzFPPcX9EKJWNJGyRAbSYCa7dMBH8jzCdCylfwSEkalNm878QSeTxZ6MThYlnhK9DacM89oSosUKyXmWAYppGnt1ccTgciWGiqUtSgrKqkCJ7xlhbMo5THiuOIzc3GXkaxomiNMxziRSCzSZRVwUhBW6ubxDXj4hzz3d+/18iQ8AImIDjWZ0jpUAkwb4fWVclWkiiSIQQeXF3R2Xz3ECLrAOoCp3FlyFhRUEcA9KUFM0SVdeM40Q/jRxPR9ruhEqRprSUVqK84PG7X2Jd1zx68oT1JkuVPyWPZvAlAjNWlwzjnKd2GIbTDiUEVVHhvGQcJpTW9H1LU5WUJvfw2dXDI2SmaHkfSclTN3l+cDqd0MLQ94fPDfznVvXb3QMvnn/MNE5477h6dI3SZxu0acq5rMwsm+DzZEkoSx813RRJZNYJ5zmYtZrVeoMtK4QuqMqSacpME6ny3+OmAa0kCc1uf8KKRF0W1E3NerPh9uaGxXJJDIFnT295+603mOdsoCjIQ5VPBzKJDIxIIXN5nxKVNaTz/5SQ59l+hBgQBIwtWSyWNFWVXSyloKgaiqrEFAWFNZz2Ww4PdzBP6OhYLSrG9kASmuPLj3jv3Te5fvYmw9AxDD1d19K1Lae2zf5BdXMWcECMHpLH+Ug3TCQk8+w4HLaM48R6tc6sptnx6tUr2r5HaYM1JnsKVBVVVWbuo5bUdc2ru9e03ecjd58b+N3DayChbUaOYiRr5shCx5SyTHiapsyBi5lOtawKDt3Id3/4HFIihezoRIJ5mrBGc7lZZ1YNCYRBiERZZSmW0SbnNp0HF1IpqiqrcaVSaGN449mbNE3D69ev6NsTbT8SAKOyROVTUeWnlbrVmoDgoi4otKIwCqNldrj0Aeccp/0WCRRlTVNVLJcrlhdXNKtVJoDEAClQKkn0I24eMUpSFYZpmvGy4OMPnvP2l77Co2dvEWKGW6uqoShKirOiOINHJ2IMaK2RIsu4m/XV2RwRYshSr36WqGLJxeU1z954g6qssiJXyLM8m/Mtos5St8TtzS1l0XzxwC+WG548e5eE4uH+FS9evKAoalzw2T5USR4eHogRpBL0XZvtzaae63XFV9+8JQZ/RsZFbmOMxdqSotDMY4ebM1lRyuwA5fzM7Ea0EhgjcEmhtKUoKnwIDJPn6vIKpRT3d6/QSmFNwXR2x8jsWYlW2WmLlE+9QDD6QG0NZWEyZ17mn5EyD0U+/TOtBGWV7U6WTU1d19lmJSWMgKqpebS5YFlXXF9tsqzMlDgUcxQ8vNryb//lP2Map/OYF7RWaJ2Vs1JmHx0hMmt3GDKJUpBrACkl9WJJYTWlSWiVPmMhaw3aWKQqCNFnBxBtiDGw2+3pu6xTuLy6+uKBbxYbrFGMY8eHz+949fqeYRy5vnmMtrkV2263QGa0huAoq5ppHnHDEZUmtNFUdYM2BavViqossdbQt0dSSlRVnQ0XUjorQwPDMONcBCR1VWCM4dWrT1BKc3V1QVkV9ENLVTfYsqFuFigp6SePkQIpxF9M2uAzCLWdHKdh4qqpKa2lKQxWydyrS0mIoCV5siYSxIA2uXgyMr9McR5wpy0xONZNxZPH1/gQmYWmG2ZCjEw+8skPvkc408f9NBCDI4bwmYnC8dTizmTKTyXm0zQzDPlAZbVrQqt8u45jn38/U5Jioh9GlMp6PGMs7aljHAeEFEwxm09+8RO/WDB2J453H1MJz7Mnt2dbsplHj645HvcYY1k0K5q6Yb15RNe3GJ3pV9Vig1KfpolcZTbNAjdn5ohUBpkchclWpBebC4wtGFxgdBFEphbH6DEmt4yb9ZLtwwP6fGpCcFxcXrFZNhynmQjURuVACXn2pckfM8bIfT9QW8WqKrA6iztJWSc3ziMiBayRFBKsUnmmbvINcS7DkSSskdR1AUpztz3x+n7Hy+fPmbo+1xfC0J+OeYxaL+CcEof+mHNxlc0dh2E4t8pQ1SVFYRFSEkLEh0jf9YzjwKNHVzTn9i9Ej5LxjJ/0PDzcczwd0Nqw2lzRFPYzvsK/7/l8Bs4c2d7fcXr+Q2KSLNdrYMN6vTxLePNkqB1nPv7kOUYpnj15RFnazNBJ4EPGyI1WVFVFSpHj8UBKAudnqqIihDy6rOuK4iy5HrqOcTgxh6wde+utt9Fa8eLFx0Q/IwWsVmvGruNhf2BdFbzaHdkPjlVp8mnWitH5PNDR5kzZyiYKldWcujG3W/rTtsiipUYkSN7j555arjDWIo3NY9PgKLSkLguuLjf82QcvGOdM2Hj5+jXLQvEzX/s6X/nmz3L9+BnhDAWPYySRwZoQdtl2RWqiELnYOw94sqgErC0QQtCejrT7PcfDnvXmmvLse7teX1CVJdvtPUM/5oJ0uWH2kXAmXH/hwP/ed97nnUdLrt/+ClYpLq6fsFmvMEbz+tVzpFCURUUSgtuba4iBwpaf/eIv7vZ8/5MtX3/rFmvyBzocdpDyqFTi6foWqfK0qesOaG1Zr2qs0bipRwmoVhuUlDz/5EO88yxWl8zDiaE/8Oj2mv50QqaA1Yp2cjSFwSh5pjt9Or5VZ1BHUFlL77Pb1vVqw6PNJSrFrAlUinb/wDzlwVKSikJoElBWDWaxJp32KJ0NiD++u8ecve76aWRRLBiGkdPuNQioyopsGJFdr8uqORet+jx5O1+6IiOgzjmGvstDsWbB5uLyzMULFNacwSBJ01i6rqPvO8ap5/HjxxRFQRnzBPJ4/BEcMb7x5iNKo1iuHqOVRIjcM3700XPa04nr6xva7kBdL7hcN/Tdkb7dsb64zlCpUFxfLFgvK6q6YB6HbK4gLW6aUEqRfECgSCTqes3pdMD7E1XZsNxsmIaOlAJd19F1Jy4vbzmessPksL+n3+9YLspsBmwUpzmw60c2RUFlFaUS+ASBfOU3xiKFIhIICaTShASLssbYKp+w7R3O5QHJMDraT16RYuDx4ydcv/WljMAJgfeR2QUe2i0LrVloyTBNbI8ntrs93ie0yk4h0+wYp4FH9SZX84L/P/sYzv5+Qmbks7ENWhtSCiwWDd5Hju0JJTV1s8BJx363x7ncTrp5YvYxv9T9iK42Xzzwc3+k3NwglUUpqKrs39a2J8qqOb99Wc869B1umrBl9ll7/fIV0QfeePTkMx7e8XQkpSx71rYgeM80z1ibK9Rxzs5WKUHfHREJ6nqBczN937JaZ2GhczNKaap6zXJ1wcd//u8IMRdBpcmMGYRgWWbsvdSKFCMoTVmWHIeJ+67DOYefp8xO1YqmLOh2r+lmByGitSUSs5mRtVxcPWJxeYXUiuN+x7ZtiUpzuVpxvVpRFiVjnJnmE+Vymd02Y6KuFGWh2ayvMh0bC0QOx47NevHZRgwldR5mGfsZU3m/PzFNmUhZ1Svu7+4zPetcM2ilcUEQ50A/dExVxTS0vL4f+cWf+/IXC/zt7Rt044DCsV5fME8ju4ctwefZdRIZREhhZhpH5naLNCX7w4G6WQECKVMWCRz3nE4njClpFgvmyWX92eaClDKPXSlFSh4XoCoquvaI9A4fMhM1BEjzyDgOrJbrbB+eoFldZluQs5ZeIDBnEkWpFY8v12zefIfq6jHFYs33/vgPeflv/g1CSMZ5put6nl0sMTLilaRsNhRljUgBlRxNdNhmkU9mSlTrS0xVsfv+nzP0B6YUcfPM06dP+bt//79js1mzvLxBKYmxZWbrmuyG4X2WiwspsXX2o5vnMbdx1jDMeXS7qUraNps9GmMJPtPaN5sNp+OJaRo4nQ5cXFyyWK4IPuS5RdejVaJWP8JVrw28cXlLSp6H+1cE7zESnj55fHatyntevDPUqqAo8/UkpMimCSFQN4oYPIfDHiEUMUSmKRdViYRW6ky/iqyWC0YnECFLnJvlGoJjmifGeaTtp3NRt6Hve9rTAe8Dr198zOwDPkFlDEkKUjgrYJHEcsnjn/mr3Dx9i6qqOex3pN//N5+1V8PUc3c4sTv2XFQVq+UFi/UFqiqyooWeV6+fE/c71k8daFDG8uWf/Vme/dQ3+OjP/5TXn3yMkJFHt0946+23CUiEUgjCZzy4eXY5pwvJ/Wnkcll+BsBYm00T60KhZJ2HLn2fu4KiYJ7zUodTP1E1DUVZ0vcD/TAhZI+RZBPEMFMsG1biRwj8YlEz9Cf2+wesLXn69Bmn/R2VAcF0lhPlPJmSxp792p2LSJmo6ryn5bDfEUP2Yt0+3DEM0DRLfIjs9g8YXZ7pww68y8igqlhUBdv7VyRhECI7P93dvcosm3Hgo/f/DGUsrz/8ISFGxpBQKlGd2atGayKSeRopjKWuKopS8eZ779HUFYd+YphGCmv54w8+5KpecPnln6a4eQbKoMoSZR3D0cE003xq1+oD149vePq1ryEE/PZ/9p8zDR1d13Hz7A1MVVMbSwghO4q4mZQC1mYjhhAjF4sSSaJtW4ZhwDmDlNkarrAlr16+zCheTAgkdd2clbOJrutRUnJ9/ZgXL1/Q9232AdA1VltChML+CK5Xh+0Dx7YlJbh9fMnQtwxzwpRFNvF1E67fo7TN/8g8XYsp5x+js23H8bDHFhUxegSewi7Y7R5omiXJC6QIeDex84mpO1GWBcvliuPxnpAEx4dXCFMgk+fi4iLP9iV8+ad+lruXL3gRPFYpUgqcpmxeuKnKrGhB5LHu2LNYNkgBb7z3FZ698QavtnvcPGdHKgFldMjugBh7RFlT6gqVZqSB4uYRzfVTxHm8evvWWzx98y3S2TSpKAs2V9eZlDkMZw3ffGbpngc1Mq81SYBVghgT6/UGYwvc7CjP4Jb32TvvcDhwOh2RSmJThmO32wPzNLFossHkZrPhcDx8pgtYLNYMXUvZLL544Le7LVW9Yb1e0DQNH3/4QxKKtutJaKpqQVk0iOQIbmLutiANxlbYRY3SkuPpkIu1cWS723N1cZFdoI8tRVGzWF0iBZTVkmEakYuCsqyBiHMBpQyryxvKsmK7vaM/dnmGP8+47YSxBdLWuBhRIo9sM+kyoI1Ap0ymnLqWh/sHnjx9ymJp+Ku/9hs8//hjtqes1b/ZrHn++oHpgz/jjeM9RVFyeXFFs1yxrjXN5SOiKUjBs764Yn1zmzXqKeGdpyhLSCkrc5LIAJWUWShB1iiM4/DZWjNrC1KKOSdrgyyy43VKib7vGceewirq21uKomQae/wUmd3M5BwNGfOPwXGxWfPq1StsURIjIAS77cMXD/w0e+pGsFqvGfqz5r2scang1A1IAdNwwg8HLp+8Q1lK/Dwy9XsSiqpZ0Z4OGFsiQuJivaQsa0KYeePZM+RZGjR5D0iM0pRlQV3XvHj5CSll4uE0K2KKNIsVUmmqqkEpQ9/1nLqO0zjQzx5BJliOIRHnDNZURmMXS27efo/les3kPFobvvXXfgWZIr/z//5/cdjec10pFm8+4e544qQgiEQDmOlE8+QNYlGSkmN99Yiv/PzPs1yt8vROFxyPJ4ye0VIgKBin4exTl23Ix75lmhO2LDGm+KwiH8dMTP3056QUbLc7QkhYY7PRg80auKHdY8qG25tHjOOIdzNlWUFShOhYLld0XcfzTz7g+vqW5WL5xQNfWo1WAq01d68e8jI/IVEy0o4TpEClYdy/plve4IKnKitMuSHFmTC1hHmCwiKlYrnYUFUlL1+12JUFHMk7EgXTlGU/ddPQ96ezNajKKlkhsmeuEGzWF1lQERzf+953mOfIw3ZLP2evumyYIIgx4P0MbsQosGWVq98QqcoSrSS/8p/8Hb75C3+FD/7kj3n9wZ9DiEz9SD9mIsOyKri43FBcXLG4vGJxdcWjZ2/SrC9IKVE0NUYXFGVFf9wxDCNR5j66KGpizFLmo3NMs6esCg67BxbrbHCktWXoO7quJaUa7/V50plFpFpLtCno+gFdLpBxpm1bbFHjhoHQD7kl9XPWLfYDIJhdYByOXzzwIjm8nxiHjuPxSLO8BCm5f3hAKE1dLJnkCvP057NH3PnEuX5muVownHqSyO5NRVEglQUhuLq6xlpDd9pnFw0chVXZUJhIezrmXKrAx+zmmIWaeVWZ9HlF2Gq14flHH/Fwf4cLZ52bDxQ6URuFFhnzPhxbvJvP2yQiQqizcldQvvkuqqj5xi//KmVRcrx7xfP3v8d4OlA2S5ZXl1y/8Q7Vak1VZXuTceyYhomqrlFaY6REqUccDnsgME1Tpm2Z7AI2ze4svIzUizXewRRGIFHVDbXIxkuHQ17fFqNH6Ww1Nw490ziRQiCkhCokwZ9vCylRWlPYMiuUyoK6KjgeD3Td6YsHfrFcM88z24cHpMiTIK0thZGsVitiAhEnlCnOylOJVhZhMjZ/nAZWq1uiENnhchwJPt8g0xSyLMuWpHEgScVydcHxcMiaeW0JIXPb6yq7aI3ThBTq/CFrHt8+4V/8s39M2w/os7RZytwjR6HwQtBGwdN6wcXlI7QUdN2ALSq2+z0vt0cWVcGbj6+4uroGEovNhsXNYx7u7yhsgdSKxeYCU5QM06dfdol0nuBdDvI8Aynv0FOS9XqNkpKHh/3Zjkzm/TUhsGsnjr3nyWWNlonj/gEf8hi4aVYcj0dSimdiSSREqErDcd8jCZTNkq49Ya0mJoktMoe/KCwPw2tCSripyyPpz3k+dzp3ffsEReDu7nW23nj4hNfPf4ixNhcfpaW0ilIGSpvbl93uHqUE7fEASOZhRxiPFDqyXhTYssi3wpzbMyUF1mrqOi/+2e4ezguJChaLJXVdMbu86Ggae1L0jM6z293zvT/9Iz784AefsW2sKbC2oKoqFss1VbXC1kvCWfu2vX+V00HyFBoaK6ibms3mEikFDw937HY7Vus1l1ePEFqefXxyYOd5RirLfSeo1zdU9SKzgssS52aqqsR7nwmVKVLXZQZsEHnoIhVGRC6azCXIK8bkeQFEyzxP1HWdDY27LmP+xwPj6IgIQkp4N+Gdw/n8qVOKOD8xzx2lEbhuy7K21PZHUMsiDYv1hhd373Nz8xRb1aTw/xM0AeM0EEOiqqqzPanBGsvd6+cINKqoqaoCN0+0u9doKTIqpg3jMGT2aEyIWuLOazmUNnRdS1lWHA95sU5ZaOZpwOg8fzam5P0PfpB3uSmFOI9pP11LYmyJVfo8y3YMxwOP3ngbbTTH7SuUsawqy9tvPMZay93dy+wXby3WFjy6vuF0eMi760T++7MSJtIPM30pUWmmaWoOp566WWY7tjMl2gfHxeWG0+FI37cs9Yah7wh+omqW6M2aeeoIKC4Wa6Z54HQ6Zc3gesXp1J59hB3BTyyWa6axz6TTosAiMaZgGPP+uqzKPYE06GrNYvEj2J2RcmVfFCXLzRXDOOLdxPajP+Xpl3+BYZhIZPWqD4EYPMvlCh9m3OwJMSLVSAKMMVS1JaXANI90fW7zVosGqSTTcOIwz5xOp8+8W/PQQrKsMsKltcGWNTpGXiWf/VpTwmiNNpbSFmgp8CmgpWB2E8dxoBCR4/aex+99DWs0sb7EGMX17S2QuLt7zdCPmNjTNI+Y50BZWJrFinnOwoVpGgk+EJLjqkyUDPStz1Tss1P30LfZdWrsqOrz/tcYcd4zzzN9d+Lq0SNcEAhVZnfv0xFx2GcmzjQhz+losVjQ93ndW9f3CKkZx/nsGVjg/czxtKcqDfM4cmoHimIBMTBNHrv6Efp4ITJ/vqrqc/Gxp6kqLt76GZTJ25T6YSDFgFYLXJRUZcV+/xqQFOUCIQXeTRgtzztoNUKVLJZlvrJcZq0UhcFNE8vlOuvW1xckBNaWpOSZj3f0o0PbIu9frWqkyMYIyJRnBim7YEfyCs9u6DOX32rC3KFF9rGpK8titaIoSl6/fsUwjKgwYmRgcg6tZtp2ZL3ZZMfKaWYY87r0SCDFkRAq6vOsILkp5xqhz7t7cgYNIeQ1YWfnq+wjAMPoeLFteffJJitnZk9ZlVwVNTHC89f3XE4DVd1QVQ0xRPb7HXVdU9cbhqHLRpPTSHfaY4oGoSrKsqZ9+ITZz2fB57//+dz/GvxM1+cdsSHlwqkdBp6/3uXZsXd0/Xym+GYzAR/mPC70nhgmxv6E0opT7zkOmnH09N2J/f5ICAGkoV6sUAKij9R1Q7O8wI0DXXtgdg6jNS5EFqtLtLZoU2HLkifP3kSc59lGCtw0Ms4T+1PL7riHGKitRWrBk3e+lK1X3ITUFqUNL188Z+izR229vMSs38TW2acnhHDew1Oc/W7zZ3RupqhqxjnQ9iPzNBNCzC6fCUKETz3fYozn9SXNWdmTtflWJW43JfvdLnPxbElEoc8LIRoDd88/5LDfo5XKHDspMcYi8RQ6cTjssjuWT5RF3o2HiLQu4YU9b+r+gie+PR3yaVAlh3YgJUNdqkxqIKuP73cddQHNYslykfPcPI6oIu9SF6rIs+gxIFRJknmKVBQW5yeGwbNY1BxPI8oYitKy328pjPnMLiQmqFY3dH2LH0aMKbi6vOBv/Ppvst9t+eB73yP6wNVqxccPd1gpeXZ5kdUtwNWbb1NvHlHVS1L09F1LCI79/pBvFCLKgFZ5k0RRWJTOrhPeh8+WDU/zyPF4YL3agCo4tj0ptlw/2lBWiwzJBkcIiRCytt27TNuOAYIPtF1PXdc0dUFweeXYsRtAwCgSKXimOVCtbzG2YLe/Z7lcU5aPmPqWaRqZXEKbiiRKhARBYFFmPx4hFMYUn7o9f7ETn31dNPVyw/VmwWrZUFhDs9iw223Z3r3k6mLFarEkBYc2imkcEFJRlYusD1ttKIoaKQJXmwqpCxIGowVaSa6vr7HGMs0OqbLR8Scf/5Dj6YixBYXN7FTnJ9rTMS8LJnF5ecnXvv41/s5/9d/w9NlTju0JFzxSKRZ1TSKbHf8Hv/3b/LX/6G/Rz4mun6nqmuVyyX6XtX0xBB6227ybvg+cTkeO+y0yeeaxPw+Fsgq4LAsWiwXOOZIfMTo7gy1XK+qmxFiZN0SLTLfquhNKazivKB/Hgd3uge3Da55//4+wJnPou8OO4XTkeMhbP4wxNIuaoiwpqyYvdRpa9ocDp25i9qCUJpGt22Y3g1AYa7h98gbYFUmoL37iT4cDddVkv/kQSH5EFgVSSO7vXiGi50tf+TrD7gVy+W7O+d2JJATGKvoxsNvvaNsTzk1sLh4BEaPzL/np/vhpzHtUUkrEEHn77ffOTpaBoXfEGLC2oCxLhFBYk1+GlALP3nibv/5rv85HP/whRktuH11xd7+lHRJ/9ee+wq/91t9CmYJ+GChs5p6/ev4JCUnTlFhjqess9963jjj1PL65xJYNOkVsUdEejyzXq8/66xgdELi5uUaIbOY8DD15QJW59NmtXVLX5520OrFcLdHGEOYB5+9xsyOQ9+99cnBcrmoeVRVFmUgxU9invjvr4iaa5QqtTUY5y/L8cnV854OXPL25ZFFIWldxNwi+/uRHgGwPp5bNxS3jOFAU1WdvcGENt0+eQfTYssLXGxCSEDzjMACKec66eaksq4snyJR7UiE1h8Mx76HVkFJkv3vA+UjE0dR5uOPcmMmGbUfwDmv12acurwHtTgfG9sToEj//S3+daR4R08DtW1/hd/7ZP2GzKPmV3/i1TMzUWUJd2rx893g6sVpfsFptOB4esNZSFgWbRUAurs6TruyrD5nKbMsSpTQXFxeM44jWmmHoEWikEkBmvcaYcGepky0KqrIhhHTexNliTIEsKszN15jmmBc3ELlYNizqEq0U4zAwjh3BjYSQd/Imkfv9orCM44CbPT/4sz8BKUh6A7qkH1tCSqxsmQUsXzTw4zSf0SiTc1+9oq5Kuq5lub7KGxWDQ9cX1E1DDJ62G9hcPs7V/DQj9QJlSkopMoyYNM1yyTBMTM7x2GhiDLjZZXOlOKOSRauCrh1Q2vDwcM9qvaGumuzCUVUZJxCKxaKkKAz/4W//LY7HE7eP3+Qr3/gm1uq8z+3sxFlWeXT68oNPsjumlLTHPMEa54DtBzbLmuPpxDx7pMwumKTAsslqYWPyftngPePQM44TtrAYW2O0YBpn8g66ibouz2KJHHAhBDfX1xz2D8ToKes109xx6mbqqmShFFWtOZ16jsd7UnS4aSIkhdLZW9DaCq0VTV3zsH3g5unb1HWJsnmn3t3rkeViSVmYz1y+v1Dg+2HkcGpJQFHVJGF48cnHKG2Ro8cWNTHk0yhlXrcRY94AIYLPPbq23O/uEY2lrrNtmnNgVOL6OvfRKcyUVtEUipQxqtwHG33WwT1ht99mrzrn6bqW4/GIPDtFOJd33GltqAvN8o038c7THbeIeUbUGyDLpMZppqxrqnrJ4Xhk2VQ4F3j+/BOub58y+EilRbYlsZZh6Jh9T7O4+mwzRFVZiDNd8PS9xwbNbp5ZVAWgaBYLvJvpuiOnbuDq8hJBZJpnmsWSGANt12ZLE23P1u6Jly9fs9/dI0WiKEuWl48JLmQXkn6gPe3Qpjg7a3r60VEvGtbLJdM4sGgWQMY1PvX2/0KBXzSLvEm5KJnGiYvVktd9kRmo3RGjFWVRgL1ECEnfnrJ1d7fHSPDGYsolJnSIZD+TCjVNidIGiAx9z+wSUmdzIaU006lnaA+Zl1Y2FFby1pvPCCGx3++ZxoG2bZEqc9H2h1Oedp2lRiaKvKRXa9w8kSKsF4vzyZNnznp2zv7MrVNLrFEsmgolFdM0ZK6cLbi8vGK/37LdbvPCgE1ejLyI6TwAGqiKIptCxcTxlCv/2XmSVAiZMgd+t8dYy3rZYG0BtBgJzgVe3W/Zbu+RyWFtwXKdbU7naeLi4gL76eLm/sh6s0YpQQwzSmqOAxAERZHdsV/uOgyfb370uVW91pauPbK9f4lzjuPhiC0sbX8ikSiqJarIUp9PNWAJOBxahsnz4qHlOx+8wJQ18+z48+99n5AE/TCe99EZ7l4/59T2+CjYHwd8kNhmg6k2IEtm5+j7jtNhx277muRH/JxTQFFU9H2Pc+O58m5ANxyPLR9//BHD7Kk3j1Ayc/j2+30mipqC46nndNwxDh3OzefrX+PmmYfdjmHy+KhomiXj2NH3bYZvQ2SeHabIaUQrk5cDSCjKkrwLUZ+NnxU3F2tiCLSnQ/6ekuBhnzdxWmuZJkd72tOfjogUWa8uePbG2yyXDUoKtFHsTy2nts+yNJPpbXWzIMVAe9oTXZ83eZxfxLYfmf2PANkKIYhuom4W9NOICYJ5HLi8uCLGkD+8zh62xmicmzG2QGvBbn/EVgvevM3o1zgMvPXmG7ihY4yGulBZLqQ0tqqp6prdyzvghB2m8z47wzw7tBJUVYUtGmLIxr+kT9d2zmhdnDdmeaSEu92eZV1gbMk4jpRlRtSGYUBpjbRL5pQQOpEifPL+d9FFQfnWV85rQQv2p5GbqwwV391tGce8nEBpg3OesqwoCsvlhcSFBcdji5QmL1ZqysyKjeDnKTteKEFAUmrB4TjgBex2W07HQ+bhhcD1oxuM0ZRVleXbYUQrzTyObC4vcWPJRy+3kBIXmzXa3PHy5SsuXaKwGqkyYXNdSKRInxt4kdLn/8BPnv91Pp8P6P7k+V/t85PA/5g+Pwn8j+nzk8D/mD4/CfyP6fOTwP+YPv9fYX8yi/jKSzsAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 144x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "im3 = torch.as_tensor(im2).permute(2,0,1)\n",
    "ax = show_image(im3, figsize=(2,2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@delegates(show_image, keep=True)\n",
    "def show_titled_image(o, **kwargs):\n",
    "    \"Call `show_image` destructuring `o` to `(img,title)`\"\n",
    "    show_image(o[0], title=str(o[1]), **kwargs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 144x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_titled_image((im3,'A puppy'), figsize=(2,2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Show all images `ims` as subplots with `rows` using `titles`. `suptitle` provides a way to create a figure title for all images. If you use `suptitle`, `constrained_layout` is used unless you set `constrained_layout` to `False`. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@delegates(subplots)\n",
    "def show_images(ims, nrows=1, ncols=None, titles=None, **kwargs):\n",
    "    \"Show all images `ims` as subplots with `rows` using `titles`.\"\n",
    "    if ncols is None: ncols = int(math.ceil(len(ims)/nrows))\n",
    "    if titles is None: titles = [None]*len(ims)\n",
    "    axs = subplots(nrows, ncols, **kwargs)[1].flat\n",
    "    for im,t,ax in zip(ims, titles, axs): show_image(im, ax=ax, title=t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x216 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_images((im,im3),titles=('number','puppy'),suptitle='Number Puppy',  imsize=3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`ArrayImage`, `ArrayImageBW` and `ArrayMask` are subclasses of `ndarray` that know how to show themselves."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ArrayBase(ndarray):\n",
    "    \"An `ndarray` that can modify casting behavior\"\n",
    "    @classmethod\n",
    "    def _before_cast(cls, x): return x if isinstance(x,ndarray) else array(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ArrayImageBase(ArrayBase):\n",
    "    \"Base class for arrays representing images\"\n",
    "    _show_args = {'cmap':'viridis'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        return show_image(self, ctx=ctx, **{**self._show_args, **kwargs})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ArrayImage(ArrayImageBase):\n",
    "    \"An array representing an image\"\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ArrayImageBW(ArrayImage):\n",
    "    \"An array representing an image\"\n",
    "    _show_args = {'cmap':'Greys'}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ArrayMask(ArrayImageBase):\n",
    "    \"An array representing an image mask\"\n",
    "    _show_args = {'alpha':0.5, 'cmap':'tab20', 'interpolation':'nearest'}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "im = Image.open(TEST_IMAGE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "im_t = cast(im, ArrayImage)\n",
    "test_eq(type(im_t), ArrayImage)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAH4AAABZCAYAAAD4ipAGAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/d3fzzAAAACXBIWXMAAAsTAAALEwEAmpwYAABN20lEQVR4nO392Y+uWXbeB/72+E7fFBEnIs6Qc40sFlkkJVKUSJqUadKWLRke0AakBtx3gv+Pvuqb/jcafdFo9IAWWm5rJC1ZIkWWSJFVZFVlVg5niohvfOc99cX+MtltQEkg68KAq95CAlknAwfxfevde631rOd5lkgp8ZPnx++R/0v/Aj95/pd5fhL4H9PnJ4H/MX1+Evgf0+cngf8xfX4S+B/TR3/ef/zn/+xfp2k6MbR7mtUj9qcBJWFZGd565z3uH14zDANSSBbLNVoJnA+cTkfcNGJsTVmWXFysKMqCvhv54z/+I/aHLdZalDC8//6f80/+8f+H97/3PaSQFGWDUYpFXfPk9pb/8u/9b/nWL/wiL198whwl7771jMuLC4QQnE4HZjeilKEsSwBSioQQ6fsBpSR93yNSoFluKEvLYtFgbcnLly8hSSCyfXhJTIK6tNSLC5arJVorhJDs91vKssK5GRD0o6cuLP35cxtrGMeRh4c7yrKhLCx13XB//4qrq2vatgMk+/2Bi4sL6rpguVoQQmC33XE4HrC2QAow2vLRJx/R1EuOxx2Xl48YhoEkFFJqju0R72aaZkFdL0hhJvhAURr2+yPHw4m6LtHa8Prunr//9/9b8YUCP88zXXfCaEMEri7WdF2HLSyQaOqGcZgAyTT2BKWxRcmyaSguL1FGUpYVKcE4ToTgeO+9LzGMT9BKUpQlX/361/jWz/0S//f/2/+Ff/qP/iHeTUhR0g09dw9bfvef/CMur664uNxweXnDctUgBLx8+RJjDcvlGjePzPNIVdWEAEpCXZUkIbFFhUgBIRXWFlhrOez3SKkASYqJ9eYaYw1VVVGWJTEGQvCklDBa0XUdAoUQoERCKsEwTEiRkGpBUVTc3Dyma3tijPR9R10v2O4eWK8umaaRN954QtPUCCGY55n9fsc0OZaLJd57pmlGKs2Tx0/YbvPLJqXEGA1CIKXgoinox4RRiod9i5GBZV1SljVNPdN3A94HvPd4N3zuif/cq15pwcXmksVyzcPDPUM/MDhFwhJToq5rUvJIKbBFgVQSKSWL1YLVZkVZVnRdxzhMTNPM0LcUVvH0yRPWmw1NU7NoGt56601+87f+U3711/8mgUCKnuAj7dDzwQ8+4Hf/yT/i0aNrLq82xBh52N4jhECQGIeBql5QFCXzNKC1Rsj8Ap56R99PvP/xPSkJqqpiGAaGcSKGSAgztqhYrtZcXl5SVRUxBpybPwuQkAopJBBQWlGWBTFG6qYEmRBS40NEa0XTNEgpAUFZljTNAh9misJycbnCFpp+aDkcDoBGKQuAtSVlVeFDpKprmqZmuVrSLFYgBAIYxw5TFCyXa2bnuFhWvPPmM54+e8I4dnR9x2JZkRCEmFitLj438J974pumxvVHfJK8+ewNfAgUZaJZlDjnKJqGsioRGJq6pqwsQki89/T9QAyRlCQ+BpQ2GFvz+v6e91YrmqbG+wA4UpJ87atfZrX8u/Rdy7d/719jrCYhOA0jP/izP+f5xx9SlhVt16GkpF43uGkkIRj6kaapKYqCrjshpcJ7QZg6PvrkY07twOVSMfR7pnFivbli9g5SwFqFtRYpJc5NCCFJCWJMSKlRUrJ4tCQEzzx7Yox471kuGpq6YnIg8YzDxGKxwHuHlIqUBOvVktPphDaavh84Hk+QQJDQRhFjwGjNoeuxxuDnkVOcKauKw+FASicWyzV+HtHaMM8jdb3ktlmglSKmwPZhi5sj1hQIIVmvLR99/Bz5l1Rvnxv4GANz1Dg3IZWkPR3OubQmBMfsZhaLJc45hITdbkdKAq0Mxlqc90gJxlqGfmSeJmoDfd+xXC4JIWCMRcmcT996603+9n/+X/HRDz9g+3BPJOJiQIrE//X//H/iv/57/y1vv/seAsH99gGFJwrDZrNmf+qpS01dL3j+8Uf88P3v8+++/Yd89P3vM7Yt/4NRWFuy3mx49s67vPHee/z0z/4cWucACJFQSuFmjxAS5/JNloC2bVksligVEELhvUcIgdYGNw9MfkYqRYiRpqmRUlLVFUpJhBDcP9whUEzzxHq9JiWd04hRJJFri5RAaY13jqouuHp0w+tXz9FGE2IEAs2i4erqkhAC+/2R7W6LURptJMY2TF5TmsDtzSM+ef76iwfe+4g2krKsczFB4mKzoapz3nbzTIyBcRhxLmC0YZo9Xk6MY09KUDc1UkjKwhDcTLO5ghSRQrBc5vwWpCDESFFWvPvul/jZn/sF/tE//AckApMfSDHxO7/zOzTLhv/iv/l7XN8+RWtDqTSqqCAlvPe8evnA8w+/xx///u/znW//Pm5yCKFICOQo6FPP7uHAi49f8u1/9a/5g3/5L/ny17/O13/6mzx96x2MsaQkUEoyjg6tDcZI9vsOIQSr1Yq+H84pIaKUZrFsKMqC43GPUvKzmyelRNseOLUtVVXj5on1+oIQPTEk+r6jLPNN0zQ1x2NHVTZMYqRrTxgjubm+5YMPfsDV1Q2zm7i+ucH7yAcfvE9MiaqscM5hbcPDbk+QFcZYNusVXT99buDF5w1p/uRP/jTFGBFwvlJblBT4GElJYE0BCJQyFIUhAQ/3rxDRkaRltVqRgsN7R1EtEVKwfdjS1BWLxZKqqRBCME0TMQamyRGC4N9++w/4P/4f/vdsd3sigrookSKxrCy/9R//Nv/l3/3fsbm4ZBp7xtGz3d7x4off43t/9Ifcv3iBHyfc7CBBAqTWkBJziJAgaEOMAmkMi6bh6vqKd7/6FX7uF/8aj26esFzWOOcJwVMUBeM4IRAslg3jOOJmjzGWkBLWKgQ5NRRFgVKKaRo5nU6M44iSBmMMiEDf9yhZgIi0pw7vZ1brNYUtGaeZeRpxfkZKRfABKcH7RNsduL6+ZRwmdvsdQoDRGkQuTqUUlGVN1x6Z3chqfUXwgd/4m7/yxar64+FACBEhoKorun7A2hpjLHVVkMhFjw+JkBLDOFKVBXM/UNZLpJI4DwiJlAKlC7quQ2sJvSYiuLhYnfPip1en45133uHJs2e8vntNSoKgJEkI5lnxP/7Tfw5K81/8b/4u7fYV3/mTP+HPvv1vONzfMfUTx3HEO4+SAq00xITSksIUaK2wxiK0RCrDFAXzNPHq1R1dO/DhD97nm9/6Fr/0q7/GxdUVKSWUkhSFJcYIkIvI+YQQ0FQWpTRCCPL5STw83DOOI0VRslqtkFLh3ExKGiklKQX6rkUmT6EFKSVOXU/X97h5pK5KYpI4YF3nDunFi8jHH3+IUhZBYLO+xEXFPA7MYaK0FUjBOM+QBPv9Hq3/vTH/ywMvVEkIgUVlubxYMw4D8zyhZGK3awGBtYaIxgfHMPRsVhu6YcSqGnSBCBI/DTy8/oTVxRPefvsdpJIkBEkoYoSqqmjblnnO12tRGn7rP/5b/OAH77PbbhmnCSElMSVSDPzB7/4O/rAn+JmHF8/pu57ZB7pxYpxdvgaNwcmAUQbpI07kl2EeBrT1KBO4WDQkaRiDIDjP9mHPH/yr3yPEyG/97b/DYtGQUsz5VynaNn9mYzSzmxAyEeNIOqeaaZrouly/KCXPf+7QOvfhUkoOhz3L1ZqyKJBSIqTk1PaU1tL1HSl5mrpgubpgnHq2ux0hRuqqQSpFjAnvZ6wp8UoxDIpSaI6HHX3fYk3FerPBu/GLB34YZ5QIkDRSKaw1aK2o6hK/d6QkmOZA252oFyuausYUFbe3T3FRoqREWk9drehVJAnFD5+/QGnF09snSOFxbsZayzhObLcPXKxXKKn4+je+xdO33ma/3+KCRyMhSi6XG66akvf/9E/wMdJPM+M0MTtPTAEpFFLKXBCd2zAhLVKAEAKlBbls98zjgFYzq2aBMgInNN4F/vgP/i1GK/7af/DruZ9WkhgTQz8hlaIoCqxR58pfQQJpDHVdU5UFx1MGbYqiJMaImz2JOd+cVQ2A8y7fKNqglcBWJVVd4dxEXVX0Q8/r13ekBEVRUFc1D9s7FosLvJ+Z3YQUAnxPXazxk6WqFhitGPojPnw+z+JzA19ana9GpQjBI6TCz579bosQgmbRkFDUdcNi0SClwBhJSApcoD3c0ZQFbgpUiwvafmCaRp5d3LJZ1RijmKaJ/W6PtZarqwsUKefL0vLrv/43+fAHf87Q9liluFkvuGgqtrsDzntCSrTjhI8RIyRKG5RUpBQZnEM4iNogK0MkMvsRayzWKESUhAApRsKxpV6CloqqrklS8N1/+8dsNhe8942fZbNZUZSaGOF4arFlSVVaYgzEmLsfgcAYg/cGJTXGaKoq1wcperSxTNOI0QatNbNzhAjOJaZxousGlBJYa9kdjtzd3bFaLmmaJf3QQUys15e0XUdZLhB4pAgsa8sw9GitWa02jOPA0B1Zr3+EPn63vePq0Q3eTWziMuczGamLJVKJz64xZQzOzXRdx6OrKxLghxatLC93E8M08+6zmkeXK64v15RVfrNPpx7nAlIpjDZUZYkbW5zzVFbz9a9/g69/46f5k2//Ic8u1qzKivv9kZQCEsHsAy6EfKVKQfARpQRaSpRWFEqjpaSbRi7Xa2KIDG4mIPAxsDA5dyujCCGhCIztAVs5jFrz3T/8PZZXV6w3S4SAotA0sWaeZpTIOTTEiCBX+FJKlNIYm5HN+Zxzc8vo0KbMuTclIDL7SNcN1IXCaIU2BbNzxJBYLtcoY0FpinoFKRL7gao2HPd3rDeXDP1IYWsQEVtWHE8Ddd0QY+Dy8kcIvAo9Mk6UdolUGbUahxnnA9MYqK2krkqm2RH8DCnlXr9uMFphyxrHyGZVs1zWGKPx3nM47Ag+IqQGYfKX5GYSFls1jLOjKCyPHl3xN/76rxAe7gjTxKEfGd2MVQIXYfCBGBNKcu40wEoFMSISoDVKWwSC19s9dbOAlCgNaK1RQpCkJimTK2TySzOeWsauI/qB7uEVhf2ZXMBJidECa/JpL4oCe66hnMvgjtYZEEop9/pCgdElwXseToHaBObhgJQ6t2H9HVYYCqOJPiGSJEZHCgM+emJRMU6BaRqJSYCy2CIfHKUMicB+t6WuV0xzZLNeslot0fpzQ/v5gV9fv4WtS9T5qrc2B0kKwaqpqasSqSRCZIizritiiiipKBcVWkue1SVSwjiMtKcTtihRyuLmnsPuNbZcUFpD3+6pFytiWSFVQUo9bu55eP4xwzhy6obz6UpMUeBjIgIxgULhY0CIyOwmrDIoIXAhImUGYrQtEDGitGL2AVNUzFIjpEQmiUcilc4zBKWJIXDaHvjDf/5PuXr8lHe+/FUQgmkYEEKwWK3PwA9Iqc6FmkLBGbbVKK3Z7ntWVYGSirrUSAJSWYQQHE8nkIKqbnDHB5ASUa7RynDstnTtC96sG0qjECERk0CaghTWdIdXXF1cslqvMLrg1B4xMrJoKoSQfPzJJ3zzm1/9gideW+5ffULZrJmGE1fXtyASiEhRGKS2CJEQJGxRYq3FWoO1FiHIRcg84b1HSk1VLwnBQUpYW1HXEUREENjfv0Jqg9YFCcE4OX73v/8H/Jt/8T+ybwdG53DeUWiFFIKYIKaE1hofA1pljLLQhsLa3MrJ8ylWmkfrOvfYPjLOjjkExDxjjQYlSSEgrUGrjM3rsjynrJH/6R/8P0m//Z9ycfuEuq7x85iBp3Ofn1JiHEeElGglSDFDskpKNnWBkAKlFOtC0B47EOADlNZg1RJrCszlDdPksEWBD4nV5hJjDVIk3DyhRKK0AlsZxnZmUTfM88zr16+QUrDZbBiGgY8/+pAEzLP74ic+BEd3PFA3G1KSGYIkX2vjOOTRqpSs1us8HBGCGCNde2KeZ7S22MJSlCXOJ3zwuMkR44zSBdoUCBFRUnD7xjtEJOM0EELg+9/9Dv/qd36H+8OROYQzbEl+oUIkQq5qAUH+M4SAEInzzLJU1EXB7eWGyiiePb7GGMu+G3n1cCDESKk1i9pSaInRColDy/y5hcyAVF0uCGPHt//xP+Tq7S/x5le+ynJzyTB5bGFw80xVN3gfECRSzL0/5O/CGAWkMxo48tHHz1mtlhRlTQozp5cf0pcVt2+9i/AwTjMxJo7tieur63NtYfFuoqobZjfj557VeolSir6fmCfPHB0CaJoFUhqG8fOnc39p4J+982WEVEAEBFVdEkJis7k4p4D5jHI5QOS5dZIUxQIh82gXPCEJSiOxTcPhBIoEKQd0njwhBIbxhDWWYRj53f/hv2e7P5GSQJy/xBgjzksKo88Bzyc/xEQkoqVCS8GqKnn39pKnt9eU1hCiYDi1dEKhq4bbqzXRTxAiIXrakyMKgZtmrDUUhaWbW4yyDGNCa0Xatrz//Y/44//pX7HcbCibBddvvMHF9TVSaea+pagqLm9usWWNUJqmbtBGfTa42u0PrFYXGA1lYYlBUSw3LC4ukVLR9SNKSsrS8OjqGlto5nkm+ImiKDC2YLs95LZU5RmKVpJgJFW1xE0D49SDkFRV9cUDf3V5RUwRYwwpRcZxRAqBMorTcUdKIJWiKmuUtmitqaqK3fYBbQxCSNq2RZ0xAB80KuWxK0lTlDnIUmmk0rTdQOs9u7tXfPj+95l9ACkQSUICFwJSCmTIEHKhNQKBEKBlhmUro/nm209YVQXt4cDrwSGNxWhNSuCHgHMT0TvqqkIiiEITU8ILQ3QgS0vQhhA8vh9JIVJVZYZ76Rm6EW0NL374AUJKxnGCqWNRl2xubnj21a/x1te+gRC36NlQ1RUheIw2SAlNZQgxoU3B1ZM3kUqx6yOyWJFczzyONE2DEBrw+Lll0VSfdQNlWbDbbnEhYrTE2oLtwx2LRck8OYyVDEP3xQO/3d0RQsyFixAoqSnKEiFEhm61IUaPtQXz7NFGU5ZVJg8gUFIxz56+P3B5eUUI+ZRqJQhuJEaTkb8Y83AnCeZp5MWHH9K2LTHlAg4EIUFKiRgjc0pIIYlKEs84xboseLxZcbtZEmfH635kcoF2mvNo1Rq0rUAaEorRzwynjsIWeTycIvoMv4phQhrDFCPjNGGVhDHnzXK2pJRomhpERhOnrqU/bDnJxPHuNXcfvM+L7/4pX/vlX+Wdb3wLpRRGa5QyeB+BiBE5RfVeIbxnWUhkaTmeHETohhnvW5xz1HWNKQrGYSR4T11btIxIXTDMnraPFNaipIHkOR17NpePvnjg62qFVIoUA0kI9scWoRPedZTFhpg8pEg/DLmVmTVlGdDa5L9ca+qqYOhOtKcD6/UKbSw+CnwUuHlASYmxltNxh5EKJzT3zz/ETxMhxc8qd8iDkBDTGQLNhIMYE5dNxTefPOLRxZJ2dBw7xxQCg3OEmMBNiJioTU0cJ4KQzOfUkZhRUuFiRMiIUobJexQwu5kYYRp76qrC+8AUAn6emIYebUtm79AxEnzAi8Q8jiRl+Pj9j+jbf8DDq9d8/a/8EjdPn1LX9flzROZ5RgpJEAHnElYlUhIsm4KULOM4En2isCV1XaO1YRx2ICJVXVGW+RYJIbKsEiHVzD5Q1iuO3QPHw/5HCHxd473DpRmBJvgBq2tKU1OUBTEkgoiMvaMqNfvjiarKuag9toSYKMqKy8sLQopYW6GNQLiIMJEYPEJqum7gcDhgrcVPgdN+i/OBFBNCSYQU5xcgvwFCCEDktqqyfPXxFavlgrt9x4tDi4sJozSj9wgpKRDcnY5cmpJls6QbJ4Q2aJ0IQuSxrTIkkVNKSAkZIoUtGMaRECM+ZNAoCUFC0k0zYpxxbqIpSmxR0B22KFHh5YRPgu39ju5f/A6vP3yfn/213+Ddn/oZlFYADENP0yyprSZqhQ8ZAgdJShKEo2oWpJgwxjCNA9M8U1cFMQRCUnjn8W6ksAWHfmJRFbRtxBQNMH/xwOdiq6SqKqTQwCUCWK0ykhVjZJ5GKgNdP+WT41zOQX6LMjYzQaTET7nXdy4wjtNnnLuu75imkcViRdceads9QoiMD4QAnIMeI4lcuEMinZks710uWZUlL3YnXuxPHIaRprA4lXAxYlWidY59P5DMCS0gREFKAaUtxuQ6QarMb1NAmEbUmX2jqoqjd0zDgFEaVRQQPMpohr5nGDp08iRjOYwz1liWFUTn8UoxTyeOxz9j7if6w5F3v/mzlIsVZVmfW8JAjJ6x21NYi6nW57ZYE0JgnBzGWHa7B2KIFIuaaRpxzjFN/gzUJNaLAhEDZZFHzV3XfvHApwjPX3zMZr1mc3GJJCG1IkSPiIJhGHj+w+9yUUtu3/sWPkmGwVPXJUVRIACEzH21zoVcVVfAiClqgpsRQqGVohtP9N0JJRL1MhMqhRAEIHzazomMpysp8TGyLgs2VcHrw4ntMHMcZ1yI+JgQCqQUCCERpqBeaFzwHPsRXVYkzkMkY4nBQ8odiCAhU0J5h3czIiVqWzAjiCGAd2hr8d4zTAPD0BOmAW0Ms4/cn44kAYvFChcLrFJsDyfEDz9kmga605H3fv6v8Oj6hjCPVM2COQia5RU+BHyIdLsdQgiMsdgzQ2ieZ2KKDMOYC1UtSUnjg+d7H77i+tE1lZXMPtD3e8Lcf/HAu3miSCMprXGzoyosMbiMr0vJPE8Zg1ZNvn7PkGWMkaZZ0HUdCEUIDqUtMeQvr64bvJvxfso1Qt/Sde25iLSsLq8ptOI0BWIMuXuQCu8zKBFjQkvJRWU59QMPg+c4zYwuMLr8BdU+D0aSMdR1A26iPewxymBDQAiJUSqDNDHmOiIFFInj6URdFERASUFT1znNKEUIMedcY2i7EyElHroBLQRCW3wyVFFRCY2OkckHInDqBtLrB8rvfofLJ09YrdYoKej6ASklEZURQCEoy4IQIofDnrLMFK6qqtisL3La8Y4kAj4okpu4WK1Ic4+uFmAlWlb0Z9zjCwVeFhtqpVA68748mrKsccOJ/WGLkIbL66ckEl0/IaRg0ZTMs8dYw7zLeHJMklIXVGWe23ddCzEXhm17ZLu9p64qFs2a/bFlnDxWa6TMFW4i5RdLiHN+hxAiIQQOQ6SdIzFl+pY1htIaZEpMs6OoFviUaLuOkCJziqgkkDFlHMC5TCfxGbyZxsyhSzHk2YKQpPZEUZQkBEoaqrIiApv1BdE5vJ/pZ0c/jNRlgTaGql7k3zcFkpD084yeNIeHBz76zp9w9eQZhRKYZoWyNd0EjYIYZuqmpus6iiJ3SNYWaGUYpwGlcufknSfFEYFhs7nAzQPOR+ZpQCmLKcrPDfzncjH7/shHn7zg1es7+r5nCEX+Z5rpRoctKlarS1wUnI5Hgo845xiHjhgj1lqcm1gtl0DicNhzf3/HPI25b/YeayRXl1es15ecuplx8phqQXnum/3/7M2NKf9/KSWSlPnv0TF5x3QOYgyR0XukloQU2e739OMIpsCFRDd0lIVBxkDwc77aSfRdS9v3BB84tke6viPOjmEYmPuWOI+o5EnesVg0XD9+xqPbpzy+fsLFcklKiWGc0GQChg8JHxJScCZjJoZ+4MUH77O7e40qCoy1BDdjVUTJACLPE/quw/ucww+7O3bb11hboFQWcIzzgC0UZdmQS93ENA5IqRj7E276Ea76P/3Od7DacHv7mKpsQPbEaSD4wGKxQWuD0obgRhbLBYvFMnMfUoZ1ldbE4Nnutjjn0FJSaAnRE30ep9ZVjVQlL1/fcbc9kcLMOHQU8jxezTQ5OE8zP6UIxpToZ0+pJc572n4mpES0BiEFzkfWRUkSgn4eM1kjeDaLJVVRZB6g1hTG4ENgnkckoJVi27Wk4CmMYXADhICigtlB8BglCWNBtb7gzXfe5fSwYLFbcNf29OOAKCrKZkkIESsFSgqiTKAycDOMjrHP7WCMiWnsqeolzsXMpTt/xlwMe07HEzFFVpsMptXNknmaOJ12Z9FFibILikrTtQdsYRnGHwGr/5mvfzUHLyaQiroytN3A5eXlmV6sKMuS5epnCDFXqH1/LnhCoGkWGZNO0NQNEGiPB2JM1E0DSPph4tS23O1Hnt/3mNTy0SevkUqjzgOgrGz5C6xeiBz43TRzIy2EQEoBHxMhhDygiAkh4DSO7I9HYnCURcE0WS5WawpbcGxbSq1RErphgOiRQp6BIhjmCS01wzQSg6epGlKMRO/xY89ifYGta7S8wRQlT/YHvvPhDzlOE0+lRGRoE11Y0jDhUsSHhDaGxXrJ0LcEWbE9TizmxNObK4zRnNoW5wJlpVHacPv0TaTM/IcUPT5EvJtZLpfMczjfoPHMBTDE4FHKf/HA101NWWaivtYSWxgujEYpeSYfJvq+ZZ5mxqHH+QhCsVgsskhBZGi17090+wPGmIxhNw2IxDQ6psmhjeHmoibNJ45HhYugmxVa3ucqm6ya+ZTNKrUgpEg3e3otqYxCTpkL7LxHpkRhNM4H+nGi63sKLUkh1xU+ONycqU/H9kgMHisk+9MRKQQeCDHgB5cLSxKnmGldhVRM00xZNUQ3I4TMZImy5Hp9wXf5kGPX4+c5n/aiwqc8yo7ThCwLVpeXrK8es1heZJ5d9CiREUEpBX17IoSRcRR0g2PZVOfABwQRqwtMU1NWJV03IJCE6OnaUxZ7rC6ZpldfPPDLZU0MESES3s3M08Ds3GeCgqo8FzzKcHP7mN1uh/cRpVQel/qJeRyYxp55dtTNCqU04zQiRR5eaFsQUqIsNPieRW1YrWpad031/GOOkydGn2lOKeYTd+YE+BDYj46nC4uRAnemUkUpISUm59gd9oTgkLZEAEpJpFA47860cWj7nhRi7gjOFDMhBClGfAxYpRHAqe+wUlAUluBngptJMfMUwiBYFIa6sEQEPiVMghjB2IJxdiSRa46LmxvqJnPilYS3n2RGb4iJFHOBZq1F2aw26seJzXpNiolpGpldpCqrTMd2ju1uS1lqtFYYu+B0PCCl+eKB79r2My2YUploUNcFSmm0NoSYJ2LD2KNUJht2XQcpMAwnOPedUhrqRYHShrY9obXN+jQpcPNIcBP7h9dcXj9lv9uz2WzYbR+Q2kJqz1Ks/DvFT0efAlyC3gU6F6mMZgqJmGJm4wLjONL1HUblNkkAs/P4GKhNneFWlb+Cfp7wIacrIXI/HVPCnF+iGCXSJtphoK4qhBQIJXNvH/Ok0UiotOI4DZltu9lkNDKEXEWniJaCZ+++R9MsSAm6zp8p2zN1kaHaEAUXq4sswPQzUZrMLipKpNZMk8f5hJt79ocjSkm6fqKqShZVyTRlltTnPZ9b1c8uIoRB6YJh9HRdnvFqbWm7Hu9yHvHOc2pb6mZBURgEkfZ4wM0OISVlVVHXC/q+I0Y4nY7MbmYYRu7v73j+/KMz7uzPsivJcrXBLNbUViPIzBvIuT0lEPIv2rrtMFMqQXHmCxiZCZDjnIUaeTQEzge6oWe337Nvj1Q2X68JgZQSHyIhJnyIWW4dQ+7fU641XIgMztPNjjkJTL1ESEl3OjJNmYFbFRm/V0pQlCVSCqZ5yjMJrXj2ztu88/Wfyuxao9lcXCJkpm8LKZjnKZNayhIpNRBQac6s4PPfE2LKs44A1mSa9mKx4PHjJwzDyDxP+Qb9nOcvmccH2vZEVdUMfQdEqmpBCH0+hVqCgOVqSYqJ4B1SCMZxoGkWhChpypz/uq5DCoE1CjBIadg+PCAQ9P3AZnOBlJpFkwcSVVlwcX2Dip5++iGTGzIjNmSipE4KqxVBityihciiUKg5Ucj8qozzjABKo7LMKiXEWUZMiATvWFVZ+57TzxmLj/GsxgUlcuvoQkQLSakVioQQim5yhHFkOh1RwSONZVkWpBDyz2nFNE5MfUdhLRebFd/6lV9FW0PXns4wsclDrZSL0WkcEWRcQap8aLzzGeMX5G7EaoZhxM1THkkrsBq69sj9/StCSKwvbr944EXylNUCRGR2HmMMMQna457VcpVHqiGSUq4sExFJRGlNN0zU9YJmsWS/30GCqq6Z54lK50lXXVcgFJdXZ8Jg06C1Zrlc4OaJerXB6LNi5JMXHNOIO8OaQUm0zKWfC4FuCujKsKgKUsz9v4+5FimtISTQQqClJp1vDyUExMCysExNrtgn50hCEGLAao1S6rMbozSaVV1xvdlQlQXRTQx9zzR2KJeHKherFeb1HSkltJb0/UxwI9JEfuaXfoOv/fwvkGJOgcv1+kzSCGdYNnPlhRKM43g2TEjYc9uXu438s0pEdFUQQ0SbAq0t93cPpJRrkGn6Eebx3k+EUFFWBY9vHyOkYnJZ1VGWJaSZ9nRkmmd8iDRnbbeKkcl5lotlJgQISdeduLAFRVHTdUeEkJRVyeQi0+xIJJxzzMNAVVZYa1hvLjgAs7Zcrha5kh9nnPeUJudtJSHIDOFOPk/QSi0+m/2rMwlSQxZYKMsYEi92O/aHHasio3xKZObOICU+BFzIs3Yl5Rk9hGF2vDqduG97mkPL07feYVEvqLVif/eKJnpUWZNSwhZFLnCnjmUh+eXf/E1+8Td+k9Vqw/39KxIBJcUZ/uaswRcsViumaSKlxDTNaK2z9g6JEJp59jg3URYlzs95+liUnI5dbpPrBS92I8Z8vmjycwN/ffuE0+HANEqUSlgrqMv8hXs/MbSnM+HRUJbFWVasKMoKM44MY5eBHKlQQrDfZ8BhtVrTtqf874ua4C9orSGGQP/qfaguuby65qOPP+F0OnB1/ZiurPDpIwQto3PMIWaARwrUud2MEXrnaYoKrbKjheBT1EfgU0TjWTZrvHccT3vmQaKExGhNVZZURuNyBssaPwT9OGbatXPcXD1idzzQ7rasbt9CWiiUoWwWOEQWnohckYiUWJWaX/xP/g4/9xu/zcXlVa5NhEQpk0fS/ZFHjy5IMTGfkUelFO5cP/V9j5QjdbVAKkFVWYxRKJVZQ0VhcoqYJ7TW6KLgVhl0/BECX1U10TvabsSHmWZxRfCOeR5xbs4t2mKDVJkYUZX12ZNGsVqtmWeHD/na6tpjBkUmR0KzaBYcjntIgdVqhfeBeZq4fe+bOO+YppknT265uX7E61f3vAR09UCdQPQjs3e4M7Gx0BKrFd2cZ9pZPJgIMWCUwp5BqJTg+tEjVFESXGCaZ/bHHaXJgxujDY2WFKoAkXt4IwVT1l/hYyaM2qLkN3/tt1hf3+Kngfe//+dMQ0e12bBerVjUNUoAfuIrP/ctfvG3/jOqekFZlmddfEFKMzF6LjYLpBAM3jM7R6EFZWkJ80gSiqqqmaaJl6+es16tsUVJ254QQlJVDXVds9ttEUiQiboqWdaGebSfG/i/BKsfsWVDP7SE4Ll7/RLnRoZhQAiN1JYQAyQoiobRQVnlPH48HpgnzzTO7HY7JucxRclmc4n3jn7oqas6EyjdxMXFBmM1ZV3RNEumaWSzvmSxWJFkyTj0SFsShKIPkSgVU0qMPiClwiqFTLkz72b/FwxcQcbKRWRR16wWa4Zx5O5w4uLyGpdytT/HhJSZv2aVpFKKWmsKrbHyXMvILOT45b/+66gnX+IH90c+fvGC64sronc0iwZ75icWRrHcLPnlv/1fU9aLcy2UyScxZDBq6DpiAO8Dzkf8PJ2nhGRuwzznXt8UbDYX+BA4HvaklCVb49gyjtn3RirBctnQtTtijLx4+eKLn3jnPILIzc0Np/0WgLbrMaZgnCba4wFT1mzWa5zLOrsUI/v9IdOKpCQKyePHN/mNBIZhZH/Y8vAwsVqv86RrGpjnbGcyzxPt6cRyuaZrO3zwiOR46+ljZu8Yppm3liumaeBwPNHNMzE6FkUGMEQITC6wsmCkymqUGCiNou07njy6oV4vePnyNZ4MJcuY2T5KSrTM93wmceQUpRY1Lw5H3nr8jL/xc7/I5p0v8cNdz3tf/Wne3Bie/7tvs39YoLVi6luSczRlwZd//hd48tbbgOQ0OTba0rUHnHdopWgPW0KILJYrSh1JImK0xXmHqUqKyjLMiY9e3fP4akVVGaK1+UWdJkIM3N/fMY0T1zdXZ/6D4v7hkP1zvmjgU5jphg4pNaUxJKHo50AMYGxJvTj31jExDAPBe8Yze+V0ym/ezeNnGQHzWQKtreHy6pa6bhFCMbsZrfJV3LV7UopUVcPxeERIzbEbefb0BilumIXk0dUjYgi8ePGciIC2Yxw65hCotMy3QMp4thCZk0eMVKbgOAx8/NEPuNlcsNDwcBxorD1zCBJlUWC1QgqDPEusSqUpvWcIkZ/66td498tf409f9VyvI0vjUbLiO9/9I548viX6iLYGJQVVs+C9n/4mIBiHnqYwSCkYp+l8EylWl9coKZmmma49cDweuQ6RsqmJAUICJSXLuiI4TxKQksTY4tz6TQgkRSk5HTtskbkHUiiOPwoDZ/vwimkOLJfLfE0lxXK1IoZEezoSvKNcXmFsQVWVjEO2DDHWsFpd0HctU7BY6Xm921KajNOf2o7DqePJ1QVNnftoqSRDrxDC0rYdXX9iuWz4+uIdxnFinifeeOMd2tORh/s7rq9viLxGCEEnBT56aqM5zSGj+iJX9Ak4jiM3q4rGKL7z4fuMY89b149ZSs22SxRlTRSSy9JSpOwAYsnFlpWChS1YrzdY5zi8/pj/8Od/CW8Mx1PL7/zD/wd+nlhXJS441quKxlqapuLR0zdQKhMsELkOUuovvvK6zpYqxlqUljTLTM6QUrLdHVg2DfM8YM4eQTEFDsc9j29v8S4iJNRVwzD0jENPP/RYrbKxVPz8efxfwrKt0YWkrGqM1dmkYByxpqBqVshiQWkttQWtBCfnUUhk9BSFoRsE09AiC4OUkmPXoXFoEherJTElpNIUEo7HHUVRA4K6EbRdy2KxoOt62nak63qsVYQIc0i89e6XEKZiaA+07ZF4eMBmSymEEPTOUxrDMM2MzvPy0LGpShgS33/xgg9ev+b26ooUIguhWNQNF+tLyhTo+47KGKKbUGGmKCuWN28gtOGhPfF7v/cv2B0O7A573NixbmpsUUA/Uj9+RlV8m/WjK8TZDMGezRdjyMxepQuMzUqdlBIpBepmkbuaKY9+LzYbhBCM00xZGE6nPVVZsV7UzFPPcX9EKJWNJGyRAbSYCa7dMBH8jzCdCylfwSEkalNm878QSeTxZ6MThYlnhK9DacM89oSosUKyXmWAYppGnt1ccTgciWGiqUtSgrKqkCJ7xlhbMo5THiuOIzc3GXkaxomiNMxziRSCzSZRVwUhBW6ubxDXj4hzz3d+/18iQ8AImIDjWZ0jpUAkwb4fWVclWkiiSIQQeXF3R2Xz3ECLrAOoCp3FlyFhRUEcA9KUFM0SVdeM40Q/jRxPR9ruhEqRprSUVqK84PG7X2Jd1zx68oT1JkuVPyWPZvAlAjNWlwzjnKd2GIbTDiUEVVHhvGQcJpTW9H1LU5WUJvfw2dXDI2SmaHkfSclTN3l+cDqd0MLQ94fPDfznVvXb3QMvnn/MNE5477h6dI3SZxu0acq5rMwsm+DzZEkoSx813RRJZNYJ5zmYtZrVeoMtK4QuqMqSacpME6ny3+OmAa0kCc1uf8KKRF0W1E3NerPh9uaGxXJJDIFnT295+603mOdsoCjIQ5VPBzKJDIxIIXN5nxKVNaTz/5SQ59l+hBgQBIwtWSyWNFWVXSyloKgaiqrEFAWFNZz2Ww4PdzBP6OhYLSrG9kASmuPLj3jv3Te5fvYmw9AxDD1d19K1Lae2zf5BdXMWcECMHpLH+Ug3TCQk8+w4HLaM48R6tc6sptnx6tUr2r5HaYM1JnsKVBVVVWbuo5bUdc2ru9e03ecjd58b+N3DayChbUaOYiRr5shCx5SyTHiapsyBi5lOtawKDt3Id3/4HFIihezoRIJ5mrBGc7lZZ1YNCYRBiERZZSmW0SbnNp0HF1IpqiqrcaVSaGN449mbNE3D69ev6NsTbT8SAKOyROVTUeWnlbrVmoDgoi4otKIwCqNldrj0Aeccp/0WCRRlTVNVLJcrlhdXNKtVJoDEAClQKkn0I24eMUpSFYZpmvGy4OMPnvP2l77Co2dvEWKGW6uqoShKirOiOINHJ2IMaK2RIsu4m/XV2RwRYshSr36WqGLJxeU1z954g6qssiJXyLM8m/Mtos5St8TtzS1l0XzxwC+WG548e5eE4uH+FS9evKAoalzw2T5USR4eHogRpBL0XZvtzaae63XFV9+8JQZ/RsZFbmOMxdqSotDMY4ebM1lRyuwA5fzM7Ea0EhgjcEmhtKUoKnwIDJPn6vIKpRT3d6/QSmFNwXR2x8jsWYlW2WmLlE+9QDD6QG0NZWEyZ17mn5EyD0U+/TOtBGWV7U6WTU1d19lmJSWMgKqpebS5YFlXXF9tsqzMlDgUcxQ8vNryb//lP2Map/OYF7RWaJ2Vs1JmHx0hMmt3GDKJUpBrACkl9WJJYTWlSWiVPmMhaw3aWKQqCNFnBxBtiDGw2+3pu6xTuLy6+uKBbxYbrFGMY8eHz+949fqeYRy5vnmMtrkV2263QGa0huAoq5ppHnHDEZUmtNFUdYM2BavViqossdbQt0dSSlRVnQ0XUjorQwPDMONcBCR1VWCM4dWrT1BKc3V1QVkV9ENLVTfYsqFuFigp6SePkQIpxF9M2uAzCLWdHKdh4qqpKa2lKQxWydyrS0mIoCV5siYSxIA2uXgyMr9McR5wpy0xONZNxZPH1/gQmYWmG2ZCjEw+8skPvkc408f9NBCDI4bwmYnC8dTizmTKTyXm0zQzDPlAZbVrQqt8u45jn38/U5Jioh9GlMp6PGMs7aljHAeEFEwxm09+8RO/WDB2J453H1MJz7Mnt2dbsplHj645HvcYY1k0K5q6Yb15RNe3GJ3pV9Vig1KfpolcZTbNAjdn5ohUBpkchclWpBebC4wtGFxgdBFEphbH6DEmt4yb9ZLtwwP6fGpCcFxcXrFZNhynmQjURuVACXn2pckfM8bIfT9QW8WqKrA6iztJWSc3ziMiBayRFBKsUnmmbvINcS7DkSSskdR1AUpztz3x+n7Hy+fPmbo+1xfC0J+OeYxaL+CcEof+mHNxlc0dh2E4t8pQ1SVFYRFSEkLEh0jf9YzjwKNHVzTn9i9Ej5LxjJ/0PDzcczwd0Nqw2lzRFPYzvsK/7/l8Bs4c2d7fcXr+Q2KSLNdrYMN6vTxLePNkqB1nPv7kOUYpnj15RFnazNBJ4EPGyI1WVFVFSpHj8UBKAudnqqIihDy6rOuK4iy5HrqOcTgxh6wde+utt9Fa8eLFx0Q/IwWsVmvGruNhf2BdFbzaHdkPjlVp8mnWitH5PNDR5kzZyiYKldWcujG3W/rTtsiipUYkSN7j555arjDWIo3NY9PgKLSkLguuLjf82QcvGOdM2Hj5+jXLQvEzX/s6X/nmz3L9+BnhDAWPYySRwZoQdtl2RWqiELnYOw94sqgErC0QQtCejrT7PcfDnvXmmvLse7teX1CVJdvtPUM/5oJ0uWH2kXAmXH/hwP/ed97nnUdLrt/+ClYpLq6fsFmvMEbz+tVzpFCURUUSgtuba4iBwpaf/eIv7vZ8/5MtX3/rFmvyBzocdpDyqFTi6foWqfK0qesOaG1Zr2qs0bipRwmoVhuUlDz/5EO88yxWl8zDiaE/8Oj2mv50QqaA1Yp2cjSFwSh5pjt9Or5VZ1BHUFlL77Pb1vVqw6PNJSrFrAlUinb/wDzlwVKSikJoElBWDWaxJp32KJ0NiD++u8ecve76aWRRLBiGkdPuNQioyopsGJFdr8uqORet+jx5O1+6IiOgzjmGvstDsWbB5uLyzMULFNacwSBJ01i6rqPvO8ap5/HjxxRFQRnzBPJ4/BEcMb7x5iNKo1iuHqOVRIjcM3700XPa04nr6xva7kBdL7hcN/Tdkb7dsb64zlCpUFxfLFgvK6q6YB6HbK4gLW6aUEqRfECgSCTqes3pdMD7E1XZsNxsmIaOlAJd19F1Jy4vbzmessPksL+n3+9YLspsBmwUpzmw60c2RUFlFaUS+ASBfOU3xiKFIhIICaTShASLssbYKp+w7R3O5QHJMDraT16RYuDx4ydcv/WljMAJgfeR2QUe2i0LrVloyTBNbI8ntrs93ie0yk4h0+wYp4FH9SZX84L/P/sYzv5+Qmbks7ENWhtSCiwWDd5Hju0JJTV1s8BJx363x7ncTrp5YvYxv9T9iK42Xzzwc3+k3NwglUUpqKrs39a2J8qqOb99Wc869B1umrBl9ll7/fIV0QfeePTkMx7e8XQkpSx71rYgeM80z1ibK9Rxzs5WKUHfHREJ6nqBczN937JaZ2GhczNKaap6zXJ1wcd//u8IMRdBpcmMGYRgWWbsvdSKFCMoTVmWHIeJ+67DOYefp8xO1YqmLOh2r+lmByGitSUSs5mRtVxcPWJxeYXUiuN+x7ZtiUpzuVpxvVpRFiVjnJnmE+Vymd02Y6KuFGWh2ayvMh0bC0QOx47NevHZRgwldR5mGfsZU3m/PzFNmUhZ1Svu7+4zPetcM2ilcUEQ50A/dExVxTS0vL4f+cWf+/IXC/zt7Rt044DCsV5fME8ju4ctwefZdRIZREhhZhpH5naLNCX7w4G6WQECKVMWCRz3nE4njClpFgvmyWX92eaClDKPXSlFSh4XoCoquvaI9A4fMhM1BEjzyDgOrJbrbB+eoFldZluQs5ZeIDBnEkWpFY8v12zefIfq6jHFYs33/vgPeflv/g1CSMZ5put6nl0sMTLilaRsNhRljUgBlRxNdNhmkU9mSlTrS0xVsfv+nzP0B6YUcfPM06dP+bt//79js1mzvLxBKYmxZWbrmuyG4X2WiwspsXX2o5vnMbdx1jDMeXS7qUraNps9GmMJPtPaN5sNp+OJaRo4nQ5cXFyyWK4IPuS5RdejVaJWP8JVrw28cXlLSp6H+1cE7zESnj55fHatyntevDPUqqAo8/UkpMimCSFQN4oYPIfDHiEUMUSmKRdViYRW6ky/iqyWC0YnECFLnJvlGoJjmifGeaTtp3NRt6Hve9rTAe8Dr198zOwDPkFlDEkKUjgrYJHEcsnjn/mr3Dx9i6qqOex3pN//N5+1V8PUc3c4sTv2XFQVq+UFi/UFqiqyooWeV6+fE/c71k8daFDG8uWf/Vme/dQ3+OjP/5TXn3yMkJFHt0946+23CUiEUgjCZzy4eXY5pwvJ/Wnkcll+BsBYm00T60KhZJ2HLn2fu4KiYJ7zUodTP1E1DUVZ0vcD/TAhZI+RZBPEMFMsG1biRwj8YlEz9Cf2+wesLXn69Bmn/R2VAcF0lhPlPJmSxp792p2LSJmo6ryn5bDfEUP2Yt0+3DEM0DRLfIjs9g8YXZ7pww68y8igqlhUBdv7VyRhECI7P93dvcosm3Hgo/f/DGUsrz/8ISFGxpBQKlGd2atGayKSeRopjKWuKopS8eZ779HUFYd+YphGCmv54w8+5KpecPnln6a4eQbKoMoSZR3D0cE003xq1+oD149vePq1ryEE/PZ/9p8zDR1d13Hz7A1MVVMbSwghO4q4mZQC1mYjhhAjF4sSSaJtW4ZhwDmDlNkarrAlr16+zCheTAgkdd2clbOJrutRUnJ9/ZgXL1/Q9232AdA1VltChML+CK5Xh+0Dx7YlJbh9fMnQtwxzwpRFNvF1E67fo7TN/8g8XYsp5x+js23H8bDHFhUxegSewi7Y7R5omiXJC6QIeDex84mpO1GWBcvliuPxnpAEx4dXCFMgk+fi4iLP9iV8+ad+lruXL3gRPFYpUgqcpmxeuKnKrGhB5LHu2LNYNkgBb7z3FZ698QavtnvcPGdHKgFldMjugBh7RFlT6gqVZqSB4uYRzfVTxHm8evvWWzx98y3S2TSpKAs2V9eZlDkMZw3ffGbpngc1Mq81SYBVghgT6/UGYwvc7CjP4Jb32TvvcDhwOh2RSmJThmO32wPzNLFossHkZrPhcDx8pgtYLNYMXUvZLL544Le7LVW9Yb1e0DQNH3/4QxKKtutJaKpqQVk0iOQIbmLutiANxlbYRY3SkuPpkIu1cWS723N1cZFdoI8tRVGzWF0iBZTVkmEakYuCsqyBiHMBpQyryxvKsmK7vaM/dnmGP8+47YSxBdLWuBhRIo9sM+kyoI1Ap0ymnLqWh/sHnjx9ymJp+Ku/9hs8//hjtqes1b/ZrHn++oHpgz/jjeM9RVFyeXFFs1yxrjXN5SOiKUjBs764Yn1zmzXqKeGdpyhLSCkrc5LIAJWUWShB1iiM4/DZWjNrC1KKOSdrgyyy43VKib7vGceewirq21uKomQae/wUmd3M5BwNGfOPwXGxWfPq1StsURIjIAS77cMXD/w0e+pGsFqvGfqz5r2scang1A1IAdNwwg8HLp+8Q1lK/Dwy9XsSiqpZ0Z4OGFsiQuJivaQsa0KYeePZM+RZGjR5D0iM0pRlQV3XvHj5CSll4uE0K2KKNIsVUmmqqkEpQ9/1nLqO0zjQzx5BJliOIRHnDNZURmMXS27efo/les3kPFobvvXXfgWZIr/z//5/cdjec10pFm8+4e544qQgiEQDmOlE8+QNYlGSkmN99Yiv/PzPs1yt8vROFxyPJ4ye0VIgKBin4exTl23Ix75lmhO2LDGm+KwiH8dMTP3056QUbLc7QkhYY7PRg80auKHdY8qG25tHjOOIdzNlWUFShOhYLld0XcfzTz7g+vqW5WL5xQNfWo1WAq01d68e8jI/IVEy0o4TpEClYdy/plve4IKnKitMuSHFmTC1hHmCwiKlYrnYUFUlL1+12JUFHMk7EgXTlGU/ddPQ96ezNajKKlkhsmeuEGzWF1lQERzf+953mOfIw3ZLP2evumyYIIgx4P0MbsQosGWVq98QqcoSrSS/8p/8Hb75C3+FD/7kj3n9wZ9DiEz9SD9mIsOyKri43FBcXLG4vGJxdcWjZ2/SrC9IKVE0NUYXFGVFf9wxDCNR5j66KGpizFLmo3NMs6esCg67BxbrbHCktWXoO7quJaUa7/V50plFpFpLtCno+gFdLpBxpm1bbFHjhoHQD7kl9XPWLfYDIJhdYByOXzzwIjm8nxiHjuPxSLO8BCm5f3hAKE1dLJnkCvP057NH3PnEuX5muVownHqSyO5NRVEglQUhuLq6xlpDd9pnFw0chVXZUJhIezrmXKrAx+zmmIWaeVWZ9HlF2Gq14flHH/Fwf4cLZ52bDxQ6URuFFhnzPhxbvJvP2yQiQqizcldQvvkuqqj5xi//KmVRcrx7xfP3v8d4OlA2S5ZXl1y/8Q7Vak1VZXuTceyYhomqrlFaY6REqUccDnsgME1Tpm2Z7AI2ze4svIzUizXewRRGIFHVDbXIxkuHQ17fFqNH6Ww1Nw490ziRQiCkhCokwZ9vCylRWlPYMiuUyoK6KjgeD3Td6YsHfrFcM88z24cHpMiTIK0thZGsVitiAhEnlCnOylOJVhZhMjZ/nAZWq1uiENnhchwJPt8g0xSyLMuWpHEgScVydcHxcMiaeW0JIXPb6yq7aI3ThBTq/CFrHt8+4V/8s39M2w/os7RZytwjR6HwQtBGwdN6wcXlI7QUdN2ALSq2+z0vt0cWVcGbj6+4uroGEovNhsXNYx7u7yhsgdSKxeYCU5QM06dfdol0nuBdDvI8Aynv0FOS9XqNkpKHh/3Zjkzm/TUhsGsnjr3nyWWNlonj/gEf8hi4aVYcj0dSimdiSSREqErDcd8jCZTNkq49Ya0mJoktMoe/KCwPw2tCSripyyPpz3k+dzp3ffsEReDu7nW23nj4hNfPf4ixNhcfpaW0ilIGSpvbl93uHqUE7fEASOZhRxiPFDqyXhTYssi3wpzbMyUF1mrqOi/+2e4ezguJChaLJXVdMbu86Ggae1L0jM6z293zvT/9Iz784AefsW2sKbC2oKoqFss1VbXC1kvCWfu2vX+V00HyFBoaK6ibms3mEikFDw937HY7Vus1l1ePEFqefXxyYOd5RirLfSeo1zdU9SKzgssS52aqqsR7nwmVKVLXZQZsEHnoIhVGRC6azCXIK8bkeQFEyzxP1HWdDY27LmP+xwPj6IgIQkp4N+Gdw/n8qVOKOD8xzx2lEbhuy7K21PZHUMsiDYv1hhd373Nz8xRb1aTw/xM0AeM0EEOiqqqzPanBGsvd6+cINKqoqaoCN0+0u9doKTIqpg3jMGT2aEyIWuLOazmUNnRdS1lWHA95sU5ZaOZpwOg8fzam5P0PfpB3uSmFOI9pP11LYmyJVfo8y3YMxwOP3ngbbTTH7SuUsawqy9tvPMZay93dy+wXby3WFjy6vuF0eMi760T++7MSJtIPM30pUWmmaWoOp566WWY7tjMl2gfHxeWG0+FI37cs9Yah7wh+omqW6M2aeeoIKC4Wa6Z54HQ6Zc3gesXp1J59hB3BTyyWa6axz6TTosAiMaZgGPP+uqzKPYE06GrNYvEj2J2RcmVfFCXLzRXDOOLdxPajP+Xpl3+BYZhIZPWqD4EYPMvlCh9m3OwJMSLVSAKMMVS1JaXANI90fW7zVosGqSTTcOIwz5xOp8+8W/PQQrKsMsKltcGWNTpGXiWf/VpTwmiNNpbSFmgp8CmgpWB2E8dxoBCR4/aex+99DWs0sb7EGMX17S2QuLt7zdCPmNjTNI+Y50BZWJrFinnOwoVpGgk+EJLjqkyUDPStz1Tss1P30LfZdWrsqOrz/tcYcd4zzzN9d+Lq0SNcEAhVZnfv0xFx2GcmzjQhz+losVjQ93ndW9f3CKkZx/nsGVjg/czxtKcqDfM4cmoHimIBMTBNHrv6Efp4ITJ/vqrqc/Gxp6kqLt76GZTJ25T6YSDFgFYLXJRUZcV+/xqQFOUCIQXeTRgtzztoNUKVLJZlvrJcZq0UhcFNE8vlOuvW1xckBNaWpOSZj3f0o0PbIu9frWqkyMYIyJRnBim7YEfyCs9u6DOX32rC3KFF9rGpK8titaIoSl6/fsUwjKgwYmRgcg6tZtp2ZL3ZZMfKaWYY87r0SCDFkRAq6vOsILkp5xqhz7t7cgYNIeQ1YWfnq+wjAMPoeLFteffJJitnZk9ZlVwVNTHC89f3XE4DVd1QVQ0xRPb7HXVdU9cbhqHLRpPTSHfaY4oGoSrKsqZ9+ITZz2fB57//+dz/GvxM1+cdsSHlwqkdBp6/3uXZsXd0/Xym+GYzAR/mPC70nhgmxv6E0opT7zkOmnH09N2J/f5ICAGkoV6sUAKij9R1Q7O8wI0DXXtgdg6jNS5EFqtLtLZoU2HLkifP3kSc59lGCtw0Ms4T+1PL7riHGKitRWrBk3e+lK1X3ITUFqUNL188Z+izR229vMSs38TW2acnhHDew1Oc/W7zZ3RupqhqxjnQ9iPzNBNCzC6fCUKETz3fYozn9SXNWdmTtflWJW43JfvdLnPxbElEoc8LIRoDd88/5LDfo5XKHDspMcYi8RQ6cTjssjuWT5RF3o2HiLQu4YU9b+r+gie+PR3yaVAlh3YgJUNdqkxqIKuP73cddQHNYslykfPcPI6oIu9SF6rIs+gxIFRJknmKVBQW5yeGwbNY1BxPI8oYitKy328pjPnMLiQmqFY3dH2LH0aMKbi6vOBv/Ppvst9t+eB73yP6wNVqxccPd1gpeXZ5kdUtwNWbb1NvHlHVS1L09F1LCI79/pBvFCLKgFZ5k0RRWJTOrhPeh8+WDU/zyPF4YL3agCo4tj0ptlw/2lBWiwzJBkcIiRCytt27TNuOAYIPtF1PXdc0dUFweeXYsRtAwCgSKXimOVCtbzG2YLe/Z7lcU5aPmPqWaRqZXEKbiiRKhARBYFFmPx4hFMYUn7o9f7ETn31dNPVyw/VmwWrZUFhDs9iw223Z3r3k6mLFarEkBYc2imkcEFJRlYusD1ttKIoaKQJXmwqpCxIGowVaSa6vr7HGMs0OqbLR8Scf/5Dj6YixBYXN7FTnJ9rTMS8LJnF5ecnXvv41/s5/9d/w9NlTju0JFzxSKRZ1TSKbHf8Hv/3b/LX/6G/Rz4mun6nqmuVyyX6XtX0xBB6227ybvg+cTkeO+y0yeeaxPw+Fsgq4LAsWiwXOOZIfMTo7gy1XK+qmxFiZN0SLTLfquhNKazivKB/Hgd3uge3Da55//4+wJnPou8OO4XTkeMhbP4wxNIuaoiwpqyYvdRpa9ocDp25i9qCUJpGt22Y3g1AYa7h98gbYFUmoL37iT4cDddVkv/kQSH5EFgVSSO7vXiGi50tf+TrD7gVy+W7O+d2JJATGKvoxsNvvaNsTzk1sLh4BEaPzL/np/vhpzHtUUkrEEHn77ffOTpaBoXfEGLC2oCxLhFBYk1+GlALP3nibv/5rv85HP/whRktuH11xd7+lHRJ/9ee+wq/91t9CmYJ+GChs5p6/ev4JCUnTlFhjqess9963jjj1PL65xJYNOkVsUdEejyzXq8/66xgdELi5uUaIbOY8DD15QJW59NmtXVLX5520OrFcLdHGEOYB5+9xsyOQ9+99cnBcrmoeVRVFmUgxU9invjvr4iaa5QqtTUY5y/L8cnV854OXPL25ZFFIWldxNwi+/uRHgGwPp5bNxS3jOFAU1WdvcGENt0+eQfTYssLXGxCSEDzjMACKec66eaksq4snyJR7UiE1h8Mx76HVkFJkv3vA+UjE0dR5uOPcmMmGbUfwDmv12acurwHtTgfG9sToEj//S3+daR4R08DtW1/hd/7ZP2GzKPmV3/i1TMzUWUJd2rx893g6sVpfsFptOB4esNZSFgWbRUAurs6TruyrD5nKbMsSpTQXFxeM44jWmmHoEWikEkBmvcaYcGepky0KqrIhhHTexNliTIEsKszN15jmmBc3ELlYNizqEq0U4zAwjh3BjYSQd/Imkfv9orCM44CbPT/4sz8BKUh6A7qkH1tCSqxsmQUsXzTw4zSf0SiTc1+9oq5Kuq5lub7KGxWDQ9cX1E1DDJ62G9hcPs7V/DQj9QJlSkopMoyYNM1yyTBMTM7x2GhiDLjZZXOlOKOSRauCrh1Q2vDwcM9qvaGumuzCUVUZJxCKxaKkKAz/4W//LY7HE7eP3+Qr3/gm1uq8z+3sxFlWeXT68oNPsjumlLTHPMEa54DtBzbLmuPpxDx7pMwumKTAsslqYWPyftngPePQM44TtrAYW2O0YBpn8g66ibouz2KJHHAhBDfX1xz2D8ToKes109xx6mbqqmShFFWtOZ16jsd7UnS4aSIkhdLZW9DaCq0VTV3zsH3g5unb1HWJsnmn3t3rkeViSVmYz1y+v1Dg+2HkcGpJQFHVJGF48cnHKG2Ro8cWNTHk0yhlXrcRY94AIYLPPbq23O/uEY2lrrNtmnNgVOL6OvfRKcyUVtEUipQxqtwHG33WwT1ht99mrzrn6bqW4/GIPDtFOJd33GltqAvN8o038c7THbeIeUbUGyDLpMZppqxrqnrJ4Xhk2VQ4F3j+/BOub58y+EilRbYlsZZh6Jh9T7O4+mwzRFVZiDNd8PS9xwbNbp5ZVAWgaBYLvJvpuiOnbuDq8hJBZJpnmsWSGANt12ZLE23P1u6Jly9fs9/dI0WiKEuWl48JLmQXkn6gPe3Qpjg7a3r60VEvGtbLJdM4sGgWQMY1PvX2/0KBXzSLvEm5KJnGiYvVktd9kRmo3RGjFWVRgL1ECEnfnrJ1d7fHSPDGYsolJnSIZD+TCjVNidIGiAx9z+wSUmdzIaU006lnaA+Zl1Y2FFby1pvPCCGx3++ZxoG2bZEqc9H2h1Oedp2lRiaKvKRXa9w8kSKsF4vzyZNnznp2zv7MrVNLrFEsmgolFdM0ZK6cLbi8vGK/37LdbvPCgE1ejLyI6TwAGqiKIptCxcTxlCv/2XmSVAiZMgd+t8dYy3rZYG0BtBgJzgVe3W/Zbu+RyWFtwXKdbU7naeLi4gL76eLm/sh6s0YpQQwzSmqOAxAERZHdsV/uOgyfb370uVW91pauPbK9f4lzjuPhiC0sbX8ikSiqJarIUp9PNWAJOBxahsnz4qHlOx+8wJQ18+z48+99n5AE/TCe99EZ7l4/59T2+CjYHwd8kNhmg6k2IEtm5+j7jtNhx277muRH/JxTQFFU9H2Pc+O58m5ANxyPLR9//BHD7Kk3j1Ayc/j2+30mipqC46nndNwxDh3OzefrX+PmmYfdjmHy+KhomiXj2NH3bYZvQ2SeHabIaUQrk5cDSCjKkrwLUZ+NnxU3F2tiCLSnQ/6ekuBhnzdxWmuZJkd72tOfjogUWa8uePbG2yyXDUoKtFHsTy2nts+yNJPpbXWzIMVAe9oTXZ83eZxfxLYfmf2PANkKIYhuom4W9NOICYJ5HLi8uCLGkD+8zh62xmicmzG2QGvBbn/EVgvevM3o1zgMvPXmG7ihY4yGulBZLqQ0tqqp6prdyzvghB2m8z47wzw7tBJUVYUtGmLIxr+kT9d2zmhdnDdmeaSEu92eZV1gbMk4jpRlRtSGYUBpjbRL5pQQOpEifPL+d9FFQfnWV85rQQv2p5GbqwwV391tGce8nEBpg3OesqwoCsvlhcSFBcdji5QmL1ZqysyKjeDnKTteKEFAUmrB4TjgBex2W07HQ+bhhcD1oxuM0ZRVleXbYUQrzTyObC4vcWPJRy+3kBIXmzXa3PHy5SsuXaKwGqkyYXNdSKRInxt4kdLn/8BPnv91Pp8P6P7k+V/t85PA/5g+Pwn8j+nzk8D/mD4/CfyP6fOTwP+YPv9fYX8yi/jKSzsAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 144x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = im_t.show(figsize=(2,2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_fig_exists(ax)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Basics"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def __array_eq__(self:Tensor,b):\n",
    "    return torch.equal(self,b) if self.dim() else self==b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def _array2tensor(x):\n",
    "    if x.dtype==np.uint16: x = x.astype(np.float32)\n",
    "    return torch.from_numpy(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@use_kwargs_dict(dtype=None, device=None, requires_grad=False, pin_memory=False)\n",
    "def tensor(x, *rest, **kwargs):\n",
    "    \"Like `torch.as_tensor`, but handle lists too, and can pass multiple vector elements directly.\"\n",
    "    if len(rest): x = (x,)+rest\n",
    "    # There was a Pytorch bug in dataloader using num_workers>0. Haven't confirmed if fixed\n",
    "    # if isinstance(x, (tuple,list)) and len(x)==0: return tensor(0)\n",
    "    res = (x if isinstance(x, Tensor)\n",
    "           else torch.tensor(x, **kwargs) if isinstance(x, (tuple,list))\n",
    "           else _array2tensor(x) if isinstance(x, ndarray)\n",
    "           else as_tensor(x.values, **kwargs) if isinstance(x, (pd.Series, pd.DataFrame))\n",
    "           else as_tensor(x, **kwargs) if hasattr(x, '__array__') or is_iter(x)\n",
    "           else _array2tensor(array(x), **kwargs))\n",
    "    if res.dtype is torch.float64: return res.float()\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(tensor(torch.tensor([1,2,3])), torch.tensor([1,2,3]))\n",
    "test_eq(tensor(array([1,2,3])), torch.tensor([1,2,3]))\n",
    "test_eq(tensor(1,2,3), torch.tensor([1,2,3]))\n",
    "test_eq_type(tensor(1.0), torch.tensor(1.0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```set_seed``` is useful for reproducibility between runs. It is important to remember that certain classes such as ```Dataloaders``` have internal random number generators that is not effected by this function, so this must be run before such objects are created in order to guarantee reproducibility. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def set_seed(s, reproducible=False):\n",
    "    \"Set random seed for `random`, `torch`, and `numpy` (where available)\"\n",
    "    try: torch.manual_seed(s)\n",
    "    except NameError: pass\n",
    "    try: torch.cuda.manual_seed_all(s)\n",
    "    except NameError: pass\n",
    "    try: np.random.seed(s%(2**32-1))\n",
    "    except NameError: pass\n",
    "    random.seed(s)\n",
    "    if reproducible:\n",
    "        torch.backends.cudnn.deterministic = True\n",
    "        torch.backends.cudnn.benchmark = False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here is an example of how ```set_seed``` can be used to reset the state of random number generators."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a's: 0.154 0.498 0.071\n",
      "b's: 0.154 0.498 0.071\n"
     ]
    }
   ],
   "source": [
    "set_seed(2*33)\n",
    "a1 = np.random.random()\n",
    "a2 = torch.rand(())\n",
    "a3 = random.random()\n",
    "set_seed(2*33)\n",
    "b1 = np.random.random()\n",
    "b2 = torch.rand(())\n",
    "b3 = random.random()\n",
    "print('a\\'s: {0:3.3f} {1:3.3f} {2:3.3f}'.format(a1,a2,a3))\n",
    "print('b\\'s: {0:3.3f} {1:3.3f} {2:3.3f}'.format(b1,b2,a3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(a1,b1)\n",
    "test_eq(a2,b2)\n",
    "test_eq(a3,b3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```get_random_states``` and ```set_random_states``` are useful for storing a state so you can go back to it later. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def get_random_states():\n",
    "    \"Gets states for `random`, `torch`, and `numpy` random number generators\"\n",
    "    return {'random_state':random.getstate(),\n",
    "            'numpy_state':np.random.get_state(),\n",
    "            'torch_state':torch.get_rng_state(),\n",
    "            'torch_cuda_state':torch.cuda.get_rng_state_all(),\n",
    "            'torch_deterministic':torch.backends.cudnn.deterministic,\n",
    "            'torch_benchmark':torch.backends.cudnn.benchmark}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def set_random_states(random_state,numpy_state,torch_state,torch_cuda_state,torch_deterministic,torch_benchmark):\n",
    "    \"Set states for `random`, `torch`, and `numpy` random number generators\"\n",
    "    random.setstate(random_state)\n",
    "    np.random.set_state(numpy_state)\n",
    "    torch.set_rng_state(torch_state)\n",
    "    torch.cuda.set_rng_state_all(torch_cuda_state)\n",
    "    torch.backends.cudnn.deterministic=torch_deterministic\n",
    "    torch.backends.cudnn.benchmark=torch_benchmark"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below notice that the old values and rewinded values are the same because we were able to return to the previous state. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "olds:    0.435 0.134 0.023\n",
      "news:    0.246 0.363 0.227\n",
      "rewinds: 0.435 0.134 0.023\n"
     ]
    }
   ],
   "source": [
    "old_states = get_random_states()\n",
    "olds = (random.random(),np.random.random(),torch.rand(()))\n",
    "news = (random.random(),np.random.random(),torch.rand(()))\n",
    "set_random_states(**old_states)\n",
    "rewinds = (random.random(),np.random.random(),torch.rand(()))\n",
    "\n",
    "print('olds:    {0:3.3f} {1:3.3f} {2:3.3f}'.format(*olds))\n",
    "print('news:    {0:3.3f} {1:3.3f} {2:3.3f}'.format(*news))\n",
    "print('rewinds: {0:3.3f} {1:3.3f} {2:3.3f}'.format(*rewinds))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_ne(olds,news)\n",
    "test_eq(olds,rewinds)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In ```no_random``` we combine the ideas of rewinding state with ```get_random_states``` and ```set_random_states``` with the ability to ```set_seed``` and create a context manager that can allow us to control randomness in a portion of our code. \n",
    "\n",
    "Note: Similar to ```torch.random.fork_rng```, but also with ```numpy``` and ```random```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@contextmanager\n",
    "def no_random(seed=42,reproducible=True):\n",
    "    \"Stores and retrieves state of random number generators. Sets random seed for `random`, `torch`, and `numpy`.\"\n",
    "    states = get_random_states()\n",
    "    set_seed(seed,reproducible=reproducible)\n",
    "    try:\n",
    "        yield #we are managing global variables\n",
    "    finally:\n",
    "        set_random_states(**states)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here are some examples on how we can use ```no_random``` to control the randomness within a block of code.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "olds:    0.246 0.363 0.227\n",
      "new1:    0.639 0.375 0.882\n",
      "new2:    0.639 0.375 0.882\n",
      "seeded1: 0.146 0.543 0.112\n",
      "seeded2: 0.146 0.543 0.112\n",
      "rewinds: 0.246 0.363 0.227\n"
     ]
    }
   ],
   "source": [
    "states=get_random_states()\n",
    "olds = (random.random(),np.random.random(),torch.rand(()))\n",
    "set_random_states(**states) #rewinding above random calls\n",
    "\n",
    "with no_random():\n",
    "    new1 = (random.random(),np.random.random(),torch.rand(()))\n",
    "with no_random():\n",
    "    new2 = (random.random(),np.random.random(),torch.rand(()))\n",
    "with no_random(seed=100):\n",
    "    seeded1 = (random.random(),np.random.random(),torch.rand(()))\n",
    "with no_random(seed=100):\n",
    "    seeded2 = (random.random(),np.random.random(),torch.rand(()))\n",
    "        \n",
    "rewinds = (random.random(),np.random.random(),torch.rand(()))\n",
    "\n",
    "print('olds:    {0:3.3f} {1:3.3f} {2:3.3f}'.format(*olds))\n",
    "print('new1:    {0:3.3f} {1:3.3f} {2:3.3f}'.format(*new1))\n",
    "print('new2:    {0:3.3f} {1:3.3f} {2:3.3f}'.format(*new2))\n",
    "print('seeded1: {0:3.3f} {1:3.3f} {2:3.3f}'.format(*seeded1))\n",
    "print('seeded2: {0:3.3f} {1:3.3f} {2:3.3f}'.format(*seeded2))\n",
    "print('rewinds: {0:3.3f} {1:3.3f} {2:3.3f}'.format(*rewinds))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice that olds, and rewinds are alos both equal to each other. From this  we can see that everything in the ```with``` blocks did not update the state outside of the block. Inside of the block, the state is reset for any particular seed, so for the same seed you should get the same random number generator results.  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note: It is important to remember that classes like ``` Dataloader``` have internal random number generators, and ```no_random``` will have no effect on those random number generators."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_ne(olds,new1)\n",
    "test_eq(new1,new2)\n",
    "test_ne(new1,seeded1)\n",
    "test_eq(seeded1,seeded2)\n",
    "test_eq(olds,rewinds)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def unsqueeze(x, dim=-1, n=1):\n",
    "    \"Same as `torch.unsqueeze` but can add `n` dims\"\n",
    "    for _ in range(n): x = x.unsqueeze(dim)\n",
    "    return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = tensor([1])\n",
    "t2 = unsqueeze(t, n=2)\n",
    "test_eq(t2,t[:,None,None])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def unsqueeze_(x, dim=-1, n=1):\n",
    "    \"Same as `torch.unsqueeze_` but can add `n` dims\"\n",
    "    for _ in range(n): x.unsqueeze_(dim)\n",
    "    return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = tensor([1])\n",
    "unsqueeze_(t, n=2)\n",
    "test_eq(t, tensor([1]).view(1,1,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def _fa_rebuild_tensor (cls, *args, **kwargs): return cls(torch._utils._rebuild_tensor_v2(*args, **kwargs))\n",
    "def _fa_rebuild_qtensor(cls, *args, **kwargs): return cls(torch._utils._rebuild_qtensor  (*args, **kwargs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def apply(func, x, *args, **kwargs):\n",
    "    \"Apply `func` recursively to `x`, passing on args\"\n",
    "    if is_listy(x): return type(x)([apply(func, o, *args, **kwargs) for o in x])\n",
    "    if isinstance(x,dict):  return {k: apply(func, v, *args, **kwargs) for k,v in x.items()}\n",
    "    res = func(x, *args, **kwargs)\n",
    "    return res if x is None else retain_type(res, x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def maybe_gather(x, axis=0):\n",
    "    \"Gather copies of `x` on `axis` (if training is distributed)\"\n",
    "    if num_distrib()<=1: return x\n",
    "    ndim = x.ndim\n",
    "    res = [x.new_zeros(*x.shape if ndim > 0 else (1,)) for _ in range(num_distrib())]\n",
    "    torch.distributed.all_gather(res, x.contiguous() if ndim > 0 else x[None])\n",
    "    return torch.cat(res, dim=axis) if ndim > 0 else torch.cat(res, dim=axis).mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_detach(b, cpu=True, gather=True):\n",
    "    \"Recursively detach lists of tensors in `b `; put them on the CPU if `cpu=True`.\"\n",
    "    def _inner(x, cpu=True, gather=True):\n",
    "        if not isinstance(x,Tensor): return x\n",
    "        x = x.detach()\n",
    "        if gather: x = maybe_gather(x)\n",
    "        return x.cpu() if cpu else x\n",
    "    return apply(_inner, b, cpu=cpu, gather=gather)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`gather` only applies during distributed training and the result tensor will be the one gathered across processes if `gather=True` (as a result, the batch size will be multiplied by the number of processes)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_half(b):\n",
    "    \"Recursively map lists of tensors in `b ` to FP16.\"\n",
    "    return apply(lambda x: x.half() if torch.is_floating_point(x) else x, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_float(b):\n",
    "    \"Recursively map lists of int tensors in `b ` to float.\"\n",
    "    return apply(lambda x: x.float() if torch.is_floating_point(x) else x, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "# None: True if available; True: error if not available; False: use CPU\n",
    "defaults.use_cuda = None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def default_device(use_cuda=-1):\n",
    "    \"Return or set default device; `use_cuda`: None - CUDA if available; True - error if not available; False - CPU\"\n",
    "    if use_cuda != -1: defaults.use_cuda=use_cuda\n",
    "    use = defaults.use_cuda or (torch.cuda.is_available() and defaults.use_cuda is None)\n",
    "    assert torch.cuda.is_available() or not use\n",
    "    return torch.device(torch.cuda.current_device()) if use else torch.device('cpu')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# cuda\n",
    "_td = torch.device(torch.cuda.current_device())\n",
    "test_eq(default_device(None), _td)\n",
    "test_eq(default_device(True), _td)\n",
    "test_eq(default_device(False), torch.device('cpu'))\n",
    "default_device(None);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_device(b, device=None):\n",
    "    \"Recursively put `b` on `device`.\"\n",
    "    if defaults.use_cuda==False: device='cpu'\n",
    "    elif device is None: device=default_device()\n",
    "    def _inner(o): return o.to(device, non_blocking=True) if isinstance(o,Tensor) else o.to_device(device) if hasattr(o, \"to_device\") else o\n",
    "    return apply(_inner, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = to_device((3,(tensor(3),tensor(2))))\n",
    "t1,(t2,t3) = t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# cuda\n",
    "test_eq_type(t,(3,(tensor(3).cuda(),tensor(2).cuda())))\n",
    "test_eq(t2.type(), \"torch.cuda.LongTensor\")\n",
    "test_eq(t3.type(), \"torch.cuda.LongTensor\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_cpu(b):\n",
    "    \"Recursively map lists of tensors in `b ` to the cpu.\"\n",
    "    return to_device(b,'cpu')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t3 = to_cpu(t3)\n",
    "test_eq(t3.type(), \"torch.LongTensor\")\n",
    "test_eq(t3, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_np(x):\n",
    "    \"Convert a tensor to a numpy array.\"\n",
    "    return apply(lambda o: o.data.cpu().numpy(), x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t3 = to_np(t3)\n",
    "test_eq(type(t3), np.ndarray)\n",
    "test_eq(t3, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_concat(xs, dim=0):\n",
    "    \"Concat the element in `xs` (recursively if they are tuples/lists of tensors)\"\n",
    "    if not xs: return xs\n",
    "    if is_listy(xs[0]): return type(xs[0])([to_concat([x[i] for x in xs], dim=dim) for i in range_of(xs[0])])\n",
    "    if isinstance(xs[0],dict):  return {k: to_concat([x[k] for x in xs], dim=dim) for k in xs[0].keys()}\n",
    "    #We may receive xs that are not concatenable (inputs of a text classifier for instance),\n",
    "    #   in this case we return a big list\n",
    "    try:    return retain_type(torch.cat(xs, dim=dim), xs[0])\n",
    "    except: return sum([L(retain_type(o_.index_select(dim, tensor(i)).squeeze(dim), xs[0])\n",
    "                          for i in range_of(o_)) for o_ in xs], L())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(to_concat([tensor([1,2]), tensor([3,4])]), tensor([1,2,3,4]))\n",
    "test_eq(to_concat([tensor([[1,2]]), tensor([[3,4]])], dim=1), tensor([[1,2,3,4]]))\n",
    "test_eq_type(to_concat([(tensor([1,2]), tensor([3,4])), (tensor([3,4]), tensor([5,6]))]), (tensor([1,2,3,4]), tensor([3,4,5,6])))\n",
    "test_eq_type(to_concat([[tensor([1,2]), tensor([3,4])], [tensor([3,4]), tensor([5,6])]]), [tensor([1,2,3,4]), tensor([3,4,5,6])])\n",
    "test_eq_type(to_concat([(tensor([1,2]),), (tensor([3,4]),)]), (tensor([1,2,3,4]),))\n",
    "\n",
    "test_eq(to_concat([tensor([[1,2]]), tensor([[3,4], [5,6]])], dim=1), [tensor([1]),tensor([3, 5]),tensor([4, 6])])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(type(to_concat([dict(foo=tensor([1,2]), bar=tensor(3,4))])), dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Tensor subtypes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def set_meta(self:Tensor, x, as_copy=False):\n",
    "    \"Set all metadata in `__dict__`\"\n",
    "    if not hasattr(x,'__dict__'): return\n",
    "    # XXX: change to `deepcopy` once PyTorch 1.7.1 is out, and check nb 23 segmentation fit works\n",
    "    self.__dict__ = copy(x.__dict__) if as_copy else x.__dict__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "if not hasattr(torch,'as_subclass'): torch.as_subclass = torch.Tensor.as_subclass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def as_subclass(self:Tensor, typ):\n",
    "    \"Cast to `typ` and include `__dict__` and meta\"\n",
    "    return retain_meta(self, torch.as_subclass(self, typ))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`Tensor.set_meta` and `Tensor.as_subclass` work together to maintain `__dict__` after casting."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class _T(Tensor): pass\n",
    "t = tensor(1.).requires_grad_()\n",
    "t.img_size = 1\n",
    "t2 = t.as_subclass(_T)\n",
    "test_eq(t.img_size, t2.img_size)\n",
    "test_eq(t2.img_size, 1)\n",
    "assert(t2.requires_grad_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def _convert(ret, cls):\n",
    "    if isinstance(ret, torch.Tensor): ret = ret.as_subclass(cls)\n",
    "    if isinstance(ret, (tuple, list)): ret = type(ret)(_convert(r, cls) for r in ret)\n",
    "    return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TensorBase(Tensor):\n",
    "    def __new__(cls, x, **kwargs):\n",
    "        res = cast(tensor(x), cls)\n",
    "        for k,v in kwargs.items(): setattr(res, k, v)\n",
    "        return res\n",
    "\n",
    "    @classmethod\n",
    "    def _before_cast(cls, x): return tensor(x)\n",
    "    def __repr__(self): return re.sub('tensor', self.__class__.__name__, super().__repr__())\n",
    "\n",
    "    def __reduce_ex__(self,proto):\n",
    "        torch.utils.hooks.warn_if_has_hooks(self)\n",
    "        args = (type(self), self.storage(), self.storage_offset(), tuple(self.size()), self.stride())\n",
    "        if self.is_quantized: args = args + (self.q_scale(), self.q_zero_point())\n",
    "        f = _fa_rebuild_qtensor if self.is_quantized else  _fa_rebuild_tensor\n",
    "        return (f, args + (self.requires_grad, OrderedDict()))\n",
    "\n",
    "    def __torch_function__(self, func, types, args=(), kwargs=None):\n",
    "#         if func.__name__[0]!='_': print(func, types, args, kwargs)\n",
    "#         with torch._C.DisableTorchFunction(): ret = _convert(func(*args, **(kwargs or {})), self.__class__)\n",
    "        ret = super().__torch_function__(func, types, args=args, kwargs=kwargs)\n",
    "        if isinstance(ret, TensorBase): ret.set_meta(self, as_copy=True)\n",
    "        return ret\n",
    "\n",
    "    def new_tensor(self, size, dtype=None, device=None, requires_grad=False):\n",
    "        cls = type(self)\n",
    "        return self.as_subclass(Tensor).new_tensor(size, dtype=dtype, device=device, requires_grad=requires_grad).as_subclass(cls)\n",
    "\n",
    "    def new_ones(self, data, dtype=None, device=None, requires_grad=False):\n",
    "        cls = type(self)\n",
    "        return self.as_subclass(Tensor).new_ones(data, dtype=dtype, device=device, requires_grad=requires_grad).as_subclass(cls)\n",
    "\n",
    "    def new(self, x=None):\n",
    "        cls = type(self)\n",
    "        res = self.as_subclass(Tensor).new() if x is None else self.as_subclass(Tensor).new(x)\n",
    "        return res.as_subclass(cls)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class A(TensorBase):\n",
    "    def __torch_function__(self, func, types, args=(), kwargs=None):\n",
    "        if func.__name__[0]!='_': print(func, types, args, kwargs)\n",
    "        return super().__torch_function__(func, types, args, kwargs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = A(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<method 'add' of 'torch._C._TensorBase' objects> (<class '__main__.A'>, <class '__main__.TensorBase'>) (TensorBase(1), A(1)) None\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "A(2)"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "TensorBase(1)+a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "_TImage2([2.])"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class _TImage(TensorBase): pass\n",
    "class _TImage2(_TImage): pass\n",
    "# class _TFlowField(TensorBase): pass\n",
    "t1 = _TImage([1.])\n",
    "t2 = _TImage2([1.])\n",
    "t2+t1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class _T(TensorBase): pass\n",
    "\n",
    "t = _T(range(5))\n",
    "test_eq(t[0], 0)\n",
    "test_eq_type(t+1, _T(range(1,6)))\n",
    "test_eq(repr(t), '_T([0, 1, 2, 3, 4])')\n",
    "test_eq_type(t[_T([False,False,True,True,True])], _T([2,3,4]))\n",
    "test_eq_type(t[_T([2,3,4])], _T([2,3,4]))\n",
    "test_eq(type(pickle.loads(pickle.dumps(t))), _T)\n",
    "test_eq_type(t.new_ones(1), _T([1]))\n",
    "test_eq_type(t.new_tensor([1.,2.]), _T([1,2]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = tensor([1,2,3])\n",
    "m = TensorBase([False,True,True])\n",
    "test_eq(t[m], tensor([2,3]))\n",
    "t = tensor([[1,2,3],[1,2,3]])\n",
    "m = cast(tensor([[False,True,True],\n",
    "                 [False,True,True]]), TensorBase)\n",
    "test_eq(t[m], tensor([2,3,2,3]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = tensor([[1,2,3],[1,2,3]])\n",
    "t.img_size = 1\n",
    "t2 = cast(t, TensorBase)\n",
    "test_eq(t2.img_size, t.img_size)\n",
    "x = retain_type(tensor([4,5,6]), t2)\n",
    "test_eq(x.img_size, t.img_size)\n",
    "t3 = TensorBase([[1,2,3],[1,2,3]], img_size=1)\n",
    "test_eq(t3.img_size, t.img_size)\n",
    "t4 = t2+1\n",
    "t4.img_size = 2\n",
    "test_eq(t2.img_size, 1)\n",
    "test_eq(t4.img_size, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "# test of https://github.com/pytorch/pytorch/issues/47186\n",
    "class _T(TensorBase): ...\n",
    "t = _T([1.])\n",
    "test_eq_type(t.new([1,2]), _T([1.,2.]))\n",
    "test_eq_type(t.new(), _T([]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TensorImageBase(TensorBase):\n",
    "    _show_args = ArrayImageBase._show_args\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        return show_image(self, ctx=ctx, **{**self._show_args, **kwargs})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TensorImage(TensorImageBase): pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TensorImageBW(TensorImage): _show_args = ArrayImageBW._show_args"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TensorMask(TensorImageBase):\n",
    "    _show_args = ArrayMask._show_args\n",
    "\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        codes = getattr(self, 'codes', None)\n",
    "        if codes is not None: kwargs = merge({'vmin': 1, 'vmax': len(codes)}, kwargs)\n",
    "        return super().show(ctx=ctx, **kwargs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "im = Image.open(TEST_IMAGE)\n",
    "im_t = cast(array(im), TensorImage)\n",
    "test_eq(type(im_t), TensorImage)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "im_t2 = cast(tensor(1), TensorMask)\n",
    "test_eq(type(im_t2), TensorMask)\n",
    "test_eq(im_t2, tensor(1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 144x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = im_t.show(figsize=(2,2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_fig_exists(ax)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide (last test of to_concat)\n",
    "test_eq_type(to_concat([TensorImage([1,2]), TensorImage([3,4])]), TensorImage([1,2,3,4]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TensorFlowField(TensorBase):\n",
    "    def __torch_function__(self, func, types, args=(), kwargs=None):\n",
    "        convert=False\n",
    "        if func == F.grid_sample and issubclass(types[0],TensorImageBase):\n",
    "            convert,types = types[0],(torch.Tensor,torch.Tensor)\n",
    "        ret = super().__torch_function__(func, types, args=args, kwargs=kwargs)\n",
    "        if convert: ret = convert(ret)\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t1 = TensorImage([1.]).view(1,1,1,1)\n",
    "t2 = TensorFlowField([1.,1.]).view(1,1,1,2)\n",
    "test_eq_type(F.grid_sample(t1, t2), TensorImage([[[[0.25]]]]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export \n",
    "class TensorCategory(TensorBase): pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export \n",
    "class TensorMultiCategory(TensorCategory): pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TitledTensorScalar(TensorBase):\n",
    "    \"A tensor containing a scalar that has a `show` method\"\n",
    "    def show(self, **kwargs): show_title(self.item(), **kwargs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## L -"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def tensored(self:L):\n",
    "    \"`mapped(tensor)`\"\n",
    "    return self.map(tensor)\n",
    "@patch\n",
    "def stack(self:L, dim=0):\n",
    "    \"Same as `torch.stack`\"\n",
    "    return torch.stack(list(self.tensored()), dim=dim)\n",
    "@patch\n",
    "def cat  (self:L, dim=0):\n",
    "    \"Same as `torch.cat`\"\n",
    "    return torch.cat  (list(self.tensored()), dim=dim)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h4 id=\"L.tensored\" class=\"doc_header\"><code>L.tensored</code><a href=\"__main__.py#L2\" class=\"source_link\" style=\"float:right\">[source]</a></h4>\n",
       "\n",
       "> <code>L.tensored</code>()\n",
       "\n",
       "`mapped(tensor)`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(L.tensored)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There are shortcuts for `torch.stack` and `torch.cat` if your `L` contains tensors or something convertible. You can manually convert with `tensored`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = L(([1,2],[3,4]))\n",
    "test_eq(t.tensored(), [tensor(1,2),tensor(3,4)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h4 id=\"L.stack\" class=\"doc_header\"><code>L.stack</code><a href=\"__main__.py#L6\" class=\"source_link\" style=\"float:right\">[source]</a></h4>\n",
       "\n",
       "> <code>L.stack</code>(**`dim`**=*`0`*)\n",
       "\n",
       "Same as `torch.stack`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(L.stack)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(t.stack(), tensor([[1,2],[3,4]]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h4 id=\"L.cat\" class=\"doc_header\"><code>L.cat</code><a href=\"__main__.py#L10\" class=\"source_link\" style=\"float:right\">[source]</a></h4>\n",
       "\n",
       "> <code>L.cat</code>(**`dim`**=*`0`*)\n",
       "\n",
       "Same as `torch.cat`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(L.cat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(t.cat(), tensor([1,2,3,4]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Chunks"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def concat(*ls):\n",
    "    \"Concatenate tensors, arrays, lists, or tuples\"\n",
    "    if not len(ls): return []\n",
    "    it = ls[0]\n",
    "    if isinstance(it,torch.Tensor): res = torch.cat(ls)\n",
    "    elif isinstance(it,ndarray): res = np.concatenate(ls)\n",
    "    else:\n",
    "        res = itertools.chain.from_iterable(map(L,ls))\n",
    "        if isinstance(it,(tuple,list)): res = type(it)(res)\n",
    "        else: res = L(res)\n",
    "    return retain_type(res, it)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a,b,c = [1],[1,2],[1,1,2]\n",
    "test_eq(concat(a,b), c)\n",
    "test_eq_type(concat(tuple (a),tuple (b)), tuple (c))\n",
    "test_eq_type(concat(array (a),array (b)), array (c))\n",
    "test_eq_type(concat(tensor(a),tensor(b)), tensor(c))\n",
    "test_eq_type(concat(TensorBase(a),TensorBase(b)), TensorBase(c))\n",
    "test_eq_type(concat([1,1],1), [1,1,1])\n",
    "test_eq_type(concat(1,1,1), L(1,1,1))\n",
    "test_eq_type(concat(L(1,2),1), L(1,2,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class Chunks:\n",
    "    \"Slice and int indexing into a list of lists\"\n",
    "    def __init__(self, chunks, lens=None):\n",
    "        self.chunks = chunks\n",
    "        self.lens = L(map(len,self.chunks) if lens is None else lens)\n",
    "        self.cumlens = np.cumsum(0+self.lens)\n",
    "        self.totlen = self.cumlens[-1]\n",
    "\n",
    "    def __getitem__(self,i):\n",
    "        if isinstance(i,slice): return retain_type(self.getslice(i), old=self.chunks[0])\n",
    "        di,idx = self.doc_idx(i)\n",
    "        return retain_type(self.chunks[di][idx], old=self.chunks[0])\n",
    "\n",
    "    def getslice(self, i):\n",
    "        st_d,st_i = self.doc_idx(ifnone(i.start,0))\n",
    "        en_d,en_i = self.doc_idx(ifnone(i.stop,self.totlen+1))\n",
    "        res = [self.chunks[st_d][st_i:(en_i if st_d==en_d else sys.maxsize)]]\n",
    "        for b in range(st_d+1,en_d): res.append(self.chunks[b])\n",
    "        if st_d!=en_d and en_d<len(self.chunks): res.append(self.chunks[en_d][:en_i])\n",
    "        return concat(*res)\n",
    "\n",
    "    def doc_idx(self, i):\n",
    "        if i<0: i=self.totlen+i # count from end\n",
    "        docidx = np.searchsorted(self.cumlens, i+1)-1\n",
    "        cl = self.cumlens[docidx]\n",
    "        return docidx,i-cl"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "docs = L(list(string.ascii_lowercase[a:b]) for a,b in ((0,3),(3,7),(7,8),(8,16),(16,24),(24,26)))\n",
    "\n",
    "b = Chunks(docs)\n",
    "test_eq([b[ o] for o in range(0,5)], ['a','b','c','d','e'])\n",
    "test_eq([b[-o] for o in range(1,6)], ['z','y','x','w','v'])\n",
    "test_eq(b[6:13], 'g,h,i,j,k,l,m'.split(','))\n",
    "test_eq(b[20:77], 'u,v,w,x,y,z'.split(','))\n",
    "test_eq(b[:5], 'a,b,c,d,e'.split(','))\n",
    "test_eq(b[:2], 'a,b'.split(','))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = torch.arange(26)\n",
    "docs = L(t[a:b] for a,b in ((0,3),(3,7),(7,8),(8,16),(16,24),(24,26)))\n",
    "b = Chunks(docs)\n",
    "test_eq([b[ o] for o in range(0,5)], range(0,5))\n",
    "test_eq([b[-o] for o in range(1,6)], [25,24,23,22,21])\n",
    "test_eq(b[6:13], torch.arange(6,13))\n",
    "test_eq(b[20:77], torch.arange(20,26))\n",
    "test_eq(b[:5], torch.arange(5))\n",
    "test_eq(b[:2], torch.arange(2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "docs = L(TensorBase(t[a:b]) for a,b in ((0,3),(3,7),(7,8),(8,16),(16,24),(24,26)))\n",
    "b = Chunks(docs)\n",
    "test_eq_type(b[:2], TensorBase(range(2)))\n",
    "test_eq_type(b[:5], TensorBase(range(5)))\n",
    "test_eq_type(b[9:13], TensorBase(range(9,13)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Simple types"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def show_title(o, ax=None, ctx=None, label=None, color='black', **kwargs):\n",
    "    \"Set title of `ax` to `o`, or print `o` if `ax` is `None`\"\n",
    "    ax = ifnone(ax,ctx)\n",
    "    if ax is None: print(o)\n",
    "    elif hasattr(ax, 'set_title'):\n",
    "        t = ax.title.get_text()\n",
    "        if len(t) > 0: o = t+'\\n'+str(o)\n",
    "        ax.set_title(o, color=color)\n",
    "    elif isinstance(ax, pd.Series):\n",
    "        while label in ax: label += '_'\n",
    "        ax = ax.append(pd.Series({label: o}))\n",
    "    return ax"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_stdout(lambda: show_title(\"title\"), \"title\")\n",
    "# ensure that col names are unique when showing to a pandas series\n",
    "assert show_title(\"title\", ctx=pd.Series(dict(a=1)), label='a').equals(pd.Series(dict(a=1,a_='title')))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ShowTitle:\n",
    "    \"Base class that adds a simple `show`\"\n",
    "    _show_args = {'label': 'text'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        \"Show self\"\n",
    "        return show_title(str(self), ctx=ctx, **merge(self._show_args, kwargs))\n",
    "\n",
    "class TitledInt(Int, ShowTitle):\n",
    "    _show_args = {'label': 'text'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        \"Show self\"\n",
    "        return show_title(str(self), ctx=ctx, **merge(self._show_args, kwargs))\n",
    "\n",
    "class TitledFloat(Float, ShowTitle):\n",
    "    _show_args = {'label': 'text'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        \"Show self\"\n",
    "        return show_title(str(self), ctx=ctx, **merge(self._show_args, kwargs))\n",
    "\n",
    "class TitledStr(Str, ShowTitle):\n",
    "    _show_args = {'label': 'text'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        \"Show self\"\n",
    "        return show_title(str(self), ctx=ctx, **merge(self._show_args, kwargs))\n",
    "\n",
    "class TitledTuple(fastuple, ShowTitle):\n",
    "    _show_args = {'label': 'text'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        \"Show self\"\n",
    "        return show_title(str(self), ctx=ctx, **merge(self._show_args, kwargs))\n",
    "\n",
    "add_docs(TitledInt, \"An `int` with `show`\"); add_docs(TitledStr, \"An `str` with `show`\");\n",
    "add_docs(TitledFloat, \"A `float` with `show`\"); add_docs(TitledTuple, \"A `fastuple` with `show`\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h3 id=\"TitledInt\" class=\"doc_header\"><code>class</code> <code>TitledInt</code><a href=\"\" class=\"source_link\" style=\"float:right\">[source]</a></h3>\n",
       "\n",
       "> <code>TitledInt</code>() :: [`Int`](https://fastcore.fast.ai/basics#Int)\n",
       "\n",
       "An `int` with `show`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(TitledInt, title_level=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h3 id=\"TitledStr\" class=\"doc_header\"><code>class</code> <code>TitledStr</code><a href=\"\" class=\"source_link\" style=\"float:right\">[source]</a></h3>\n",
       "\n",
       "> <code>TitledStr</code>() :: [`Str`](https://fastcore.fast.ai/basics#Str)\n",
       "\n",
       "An `str` with `show`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(TitledStr, title_level=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h3 id=\"TitledFloat\" class=\"doc_header\"><code>class</code> <code>TitledFloat</code><a href=\"\" class=\"source_link\" style=\"float:right\">[source]</a></h3>\n",
       "\n",
       "> <code>TitledFloat</code>(**`x`**=*`0`*) :: [`Float`](https://fastcore.fast.ai/basics#Float)\n",
       "\n",
       "A `float` with `show`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(TitledFloat, title_level=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_stdout(lambda: TitledStr('s').show(), 's')\n",
    "test_stdout(lambda: TitledInt(1).show(), '1')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h3 id=\"TitledTuple\" class=\"doc_header\"><code>class</code> <code>TitledTuple</code><a href=\"\" class=\"source_link\" style=\"float:right\">[source]</a></h3>\n",
       "\n",
       "> <code>TitledTuple</code>(**`x`**=*`None`*, **\\*`rest`**) :: [`fastuple`](https://fastcore.fast.ai/basics#fastuple)\n",
       "\n",
       "A [`fastuple`](https://fastcore.fast.ai/basics#fastuple) with `show`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(TitledTuple, title_level=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "df = pd.DataFrame(index = range(1))\n",
    "row = df.iloc[0]\n",
    "x = TitledFloat(2.56)\n",
    "row = x.show(ctx=row, label='lbl')\n",
    "test_eq(float(row.lbl), 2.56)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def truncate(self:TitledStr, n):\n",
    "    \"Truncate self to `n`\"\n",
    "    words = self.split(' ')[:n]\n",
    "    return TitledStr(' '.join(words))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Other functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "if not hasattr(pd.DataFrame,'_old_init'): pd.DataFrame._old_init = pd.DataFrame.__init__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def __init__(self:pd.DataFrame, data=None, index=None, columns=None, dtype=None, copy=False):\n",
    "    if data is not None and isinstance(data, Tensor): data = to_np(data)\n",
    "    self._old_init(data, index=index, columns=columns, dtype=dtype, copy=copy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def get_empty_df(n):\n",
    "    \"Return `n` empty rows of a dataframe\"\n",
    "    df = pd.DataFrame(index = range(n))\n",
    "    return [df.iloc[i] for i in range(n)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def display_df(df):\n",
    "    \"Display `df` in a notebook or defaults to print\"\n",
    "    try: from IPython.display import display, HTML\n",
    "    except: return print(df)\n",
    "    display(HTML(df.to_html()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def get_first(c):\n",
    "    \"Get the first element of c, even if c is a dataframe\"\n",
    "    return getattr(c, 'iloc', c)[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def one_param(m):\n",
    "    \"First parameter in `m`\"\n",
    "    return first(m.parameters())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def item_find(x, idx=0):\n",
    "    \"Recursively takes the `idx`-th element of `x`\"\n",
    "    if is_listy(x): return item_find(x[idx])\n",
    "    if isinstance(x,dict):\n",
    "        key = list(x.keys())[idx] if isinstance(idx, int) else idx\n",
    "        return item_find(x[key])\n",
    "    return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def find_device(b):\n",
    "    \"Recursively search the device of `b`.\"\n",
    "    return item_find(b).device"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t2 = to_device(tensor(0))\n",
    "dev = default_device()\n",
    "test_eq(find_device(t2), dev)\n",
    "test_eq(find_device([t2,t2]), dev)\n",
    "test_eq(find_device({'a':t2,'b':t2}), dev)\n",
    "test_eq(find_device({'a':[[t2],[t2]],'b':t2}), dev)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def find_bs(b):\n",
    "    \"Recursively search the batch size of `b`.\"\n",
    "    return item_find(b).shape[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = torch.randn(4,5)\n",
    "test_eq(find_bs(x), 4)\n",
    "test_eq(find_bs([x, x]), 4)\n",
    "test_eq(find_bs({'a':x,'b':x}), 4)\n",
    "test_eq(find_bs({'a':[[x],[x]],'b':x}), 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def np_func(f):\n",
    "    \"Convert a function taking and returning numpy arrays to one taking and returning tensors\"\n",
    "    def _inner(*args, **kwargs):\n",
    "        nargs = [to_np(arg) if isinstance(arg,Tensor) else arg for arg in args]\n",
    "        return tensor(f(*nargs, **kwargs))\n",
    "    functools.update_wrapper(_inner, f)\n",
    "    return _inner"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This decorator is particularly useful for using numpy functions as fastai metrics, for instance:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import f1_score"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@np_func\n",
    "def f1(inp,targ): return f1_score(targ, inp)\n",
    "\n",
    "a1,a2 = array([0,1,1]),array([1,0,1])\n",
    "t = f1(tensor(a1),tensor(a2))\n",
    "test_eq(f1_score(a1,a2), t)\n",
    "assert isinstance(t,Tensor)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class Module(nn.Module, metaclass=PrePostInitMeta):\n",
    "    \"Same as `nn.Module`, but no need for subclasses to call `super().__init__`\"\n",
    "    def __pre_init__(self, *args, **kwargs): super().__init__()\n",
    "    def __init__(self): pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h3 id=\"Module\" class=\"doc_header\"><code>class</code> <code>Module</code><a href=\"\" class=\"source_link\" style=\"float:right\">[source]</a></h3>\n",
       "\n",
       "> <code>Module</code>() :: [`Module`](/torch_core.html#Module)\n",
       "\n",
       "Same as `nn.Module`, but no need for subclasses to call `super().__init__`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(Module, title_level=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([-0.4910], grad_fn=<AddBackward0>)"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class _T(Module):\n",
    "    def __init__(self): self.f = nn.Linear(1,1)\n",
    "    def forward(self,x): return self.f(x)\n",
    "\n",
    "t = _T()\n",
    "t(tensor([1.]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# export\n",
    "from torch.nn.parallel import DistributedDataParallel"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# export\n",
    "def get_model(model):\n",
    "    \"Return the model maybe wrapped inside `model`.\"\n",
    "    return model.module if isinstance(model, (DistributedDataParallel, nn.DataParallel)) else model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# export\n",
    "def one_hot(x, c):\n",
    "    \"One-hot encode `x` with `c` classes.\"\n",
    "    res = torch.zeros(c, dtype=torch.uint8)\n",
    "    if isinstance(x, Tensor) and x.numel()>0: res[x] = 1.\n",
    "    else: res[list(L(x, use_list=None))] = 1.\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(one_hot([1,4], 5), tensor(0,1,0,0,1).byte())\n",
    "test_eq(one_hot(torch.tensor([]), 5), tensor(0,0,0,0,0).byte())\n",
    "test_eq(one_hot(2, 5), tensor(0,0,1,0,0).byte())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def one_hot_decode(x, vocab=None):\n",
    "    return L(vocab[i] if vocab else i for i,x_ in enumerate(x) if x_==1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(one_hot_decode(tensor(0,1,0,0,1)), [1,4])\n",
    "test_eq(one_hot_decode(tensor(0,0,0,0,0)), [   ])\n",
    "test_eq(one_hot_decode(tensor(0,0,1,0,0)), [2  ])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def params(m):\n",
    "    \"Return all parameters of `m`\"\n",
    "    return [p for p in m.parameters()]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def trainable_params(m):\n",
    "    \"Return all trainable parameters of `m`\"\n",
    "    return [p for p in m.parameters() if p.requires_grad]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m = nn.Linear(4,5)\n",
    "test_eq(trainable_params(m), [m.weight, m.bias])\n",
    "m.weight.requires_grad_(False)\n",
    "test_eq(trainable_params(m), [m.bias])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "norm_types = (nn.BatchNorm1d, nn.BatchNorm2d, nn.BatchNorm3d, nn.InstanceNorm1d, nn.InstanceNorm2d, nn.InstanceNorm3d, nn.LayerNorm)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def norm_bias_params(m, with_bias=True):\n",
    "    \"Return all bias and BatchNorm parameters\"\n",
    "    if isinstance(m, norm_types): return L(m.parameters())\n",
    "    res = L(m.children()).map(norm_bias_params, with_bias=with_bias).concat()\n",
    "    if with_bias and getattr(m, 'bias', None) is not None: res.append(m.bias)\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for norm_func in [nn.BatchNorm1d, partial(nn.InstanceNorm1d, affine=True)]:\n",
    "    model = nn.Sequential(nn.Linear(10,20), norm_func(20), nn.Conv1d(3,4, 3))\n",
    "    test_eq(norm_bias_params(model), [model[0].bias, model[1].weight, model[1].bias, model[2].bias])\n",
    "    model = nn.ModuleList([nn.Linear(10,20, bias=False), nn.Sequential(norm_func(20), nn.Conv1d(3,4,3))])\n",
    "    test_eq(norm_bias_params(model), [model[1][0].weight, model[1][0].bias, model[1][1].bias])\n",
    "    model = nn.ModuleList([nn.Linear(10,20), nn.Sequential(norm_func(20), nn.Conv1d(3,4,3))])\n",
    "    test_eq(norm_bias_params(model, with_bias=False), [model[1][0].weight, model[1][0].bias])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def batch_to_samples(b, max_n=10):\n",
    "    \"'Transposes' a batch to (at most `max_n`) samples\"\n",
    "    if isinstance(b, Tensor): return retain_types(list(b[:max_n]), [b])\n",
    "    else:\n",
    "        res = L(b).map(partial(batch_to_samples,max_n=max_n))\n",
    "        return retain_types(res.zip(), [b])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = tensor([1,2,3])\n",
    "test_eq(batch_to_samples([t,t+1], max_n=2), ([1,2],[2,3]))\n",
    "test_eq(batch_to_samples(tensor([1,2,3]), 10), [1, 2, 3])\n",
    "test_eq(batch_to_samples([tensor([1,2,3]), tensor([4,5,6])], 10), [(1, 4), (2, 5), (3, 6)])\n",
    "test_eq(batch_to_samples([tensor([1,2,3]), tensor([4,5,6])], 2), [(1, 4), (2, 5)])\n",
    "test_eq(batch_to_samples([tensor([1,2,3]), [tensor([4,5,6]),tensor([7,8,9])]], 10), \n",
    "        [(1, (4, 7)), (2, (5, 8)), (3, (6, 9))])\n",
    "test_eq(batch_to_samples([tensor([1,2,3]), [tensor([4,5,6]),tensor([7,8,9])]], 2), [(1, (4, 7)), (2, (5, 8))])\n",
    "\n",
    "t = fastuple(tensor([1,2,3]),TensorBase([2,3,4]))\n",
    "test_eq_type(batch_to_samples(t)[0][1], TensorBase(2))\n",
    "test_eq(batch_to_samples(t).map(type), [fastuple]*3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def interp_1d(x:Tensor, xp, fp):\n",
    "    \"Same as `np.interp`\"\n",
    "    slopes = (fp[1:]-fp[:-1])/(xp[1:]-xp[:-1])\n",
    "    incx = fp[:-1] - (slopes*xp[:-1])\n",
    "    locs = (x[:,None]>=xp[None,:]).long().sum(1)-1\n",
    "    locs = locs.clamp(0,len(slopes)-1)\n",
    "    return slopes[locs]*x + incx[locs]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "brks = tensor(0,1,2,4,8,64).float()\n",
    "ys = tensor(range_of(brks)).float()\n",
    "ys /= ys[-1].item()\n",
    "pts = tensor(0.2,0.5,0.8,3,5,63)\n",
    "\n",
    "preds = pts.interp_1d(brks, ys)\n",
    "test_close(preds.numpy(), np.interp(pts.numpy(), brks.numpy(), ys.numpy()))\n",
    "\n",
    "plt.scatter(brks,ys)\n",
    "plt.scatter(pts,preds)\n",
    "plt.legend(['breaks','preds']);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def pca(x:Tensor, k=2):\n",
    "    \"Compute PCA of `x` with `k` dimensions.\"\n",
    "    x = x-torch.mean(x,0)\n",
    "    U,S,V = torch.svd(x.t())\n",
    "    return torch.mm(x,U[:,:k])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# export\n",
    "def logit(x):\n",
    "    \"Logit of `x`, clamped to avoid inf.\"\n",
    "    x = x.clamp(1e-7, 1-1e-7)\n",
    "    return -(1/x-1).log()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def num_distrib():\n",
    "    \"Return the number of processes in distributed training (if applicable).\"\n",
    "    return int(os.environ.get('WORLD_SIZE', 0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def rank_distrib():\n",
    "    \"Return the distributed rank of this process (if applicable).\"\n",
    "    return int(os.environ.get('RANK', 0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def distrib_barrier():\n",
    "    \"Place a synchronization barrier in distributed training\"\n",
    "    if num_distrib() > 1 and torch.distributed.is_initialized(): torch.distributed.barrier()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "After calling this, ALL sub-processes in the pytorch process group must arrive here before proceeding."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "# Saving arrays requires pytables - optional dependency\n",
    "try: import tables\n",
    "except: pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def _comp_filter(lib='lz4',lvl=3): return tables.Filters(complib=f'blosc:{lib}', complevel=lvl)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def save_array(p:Path, o, complib='lz4', lvl=3):\n",
    "    \"Save numpy array to a compressed `pytables` file, using compression level `lvl`\"\n",
    "    if isinstance(o,Tensor): o = to_np(o)\n",
    "    with tables.open_file(p, mode='w', filters=_comp_filter(lib=complib,lvl=lvl)) as f: f.create_carray('/', 'data', obj=o)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Compression lib can be any of: blosclz, lz4, lz4hc, snappy, zlib or zstd."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def load_array(p:Path):\n",
    "    \"Save numpy array to a `pytables` file\"\n",
    "    with tables.open_file(p, 'r') as f: return f.root.data.read()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def base_doc(elt):\n",
    "    \"Print a base documentation of `elt`\"\n",
    "    name = getattr(elt, '__qualname__', getattr(elt, '__name__', ''))\n",
    "    print(f'{name}{inspect.signature(elt)}\\n{inspect.getdoc(elt)}\\n')\n",
    "    print('To get a prettier result with hyperlinks to source code and documentation, install nbdev: pip install nbdev')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def doc(elt):\n",
    "    \"Try to use doc form nbdev and fall back to `base_doc`\"\n",
    "    try:\n",
    "        from nbdev.showdoc import doc\n",
    "        doc(elt)\n",
    "    except: base_doc(elt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def nested_reorder(t, idxs):\n",
    "    \"Reorder all tensors in `t` using `idxs`\"\n",
    "    if isinstance(t, (Tensor,L)): return t[idxs]\n",
    "    elif is_listy(t): return type(t)(nested_reorder(t_, idxs) for t_ in t)\n",
    "    if t is None: return t\n",
    "    raise TypeError(f\"Expected tensor, tuple, list or L but got {type(t)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = tensor([0,1,2,3,4,5])\n",
    "idxs = tensor([2,5,1,0,3,4])\n",
    "test_eq_type(nested_reorder(([x], x), idxs), ([idxs], idxs))\n",
    "\n",
    "y = L(0,1,2,3,4,5)\n",
    "z = L(i.item() for i in idxs)\n",
    "test_eq_type(nested_reorder((y, x), idxs), (z,idxs))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Image helpers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def make_cross_image(bw=True):\n",
    "    \"Create a tensor containing a cross image, either `bw` (True) or color\"\n",
    "    if bw:\n",
    "        im = torch.zeros(5,5)\n",
    "        im[2,:] = 1.\n",
    "        im[:,2] = 1.\n",
    "    else:\n",
    "        im = torch.zeros(3,5,5)\n",
    "        im[0,2,:] = 1.\n",
    "        im[1,:,2] = 1.\n",
    "    return im"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(make_cross_image(), cmap=\"Greys\");"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPUAAAD4CAYAAAA0L6C7AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/d3fzzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAI3klEQVR4nO3dQYic9R3G8efpJqLUgofmINnQeBCpBBoxBCGXEiykGvSqUE/CXiqsYBF7Kt6LeOklaLCgKIIeJBcJNEUEG7OJsRhXSxCLi8K2SNH0UIn+epg5pHZ3553Z95133yffDwzs7M6+8+Nlvvu+M7P8x1UlADl+0PcAANpF1EAYogbCEDUQhqiBMLu62KhtXlLvyt19DzCl830PkKuqvNH33cVbWkTdoaHt2Q0fdmjDZlFz+g2EIWogDFEDYYgaCEPUQBiiBsIQNRCGqIEwRA2EIWogDFEDYYgaCEPUQBiiBsIQNRCGqIEwRA2EaRS17WO2P7Z92fZTXQ8FYHYTlzOyvSDpb5J+IWlN0jlJD1fVh1v8ztAW3RmOoe1ZljPqzHaWMzos6XJVfVJV30h6RdKDbQ4HoD1Not4r6bNrrq+Nv/c/bC/ZXrG90tZwAKbXZIngjQ7x/3cSWFUnJJ2QOP0G+tTkSL0mad811xclfd7NOAC2q0nU5yTdbvs22zdIekjSG92OBWBWE0+/q+qq7cckvSlpQdLJqrrU+WQAZsIndAzN0PYsb2l1hk/oAK4TRA2EIWogDFEDYYgaCEPUQBiiBsIQNRCGqIEwRA2EIWogDFEDYYgaCEPUQBiiBsIQNRCGqIEwRA2EIWogDFEDYYgaCEPUQBiiBsIQNRCGqIEwRA2EIWogDFEDYYgaCEPUQBiiBsIQNRCGqIEwRA2EmRi17ZO2121/MI+BAGxPkyP1C5KOdTwHgJZMjLqq3pL05RxmAdACnlMDYXa1tSHbS5KW2toegNm4qibfyN4v6VRVHWi0UXvyRjGboe1Z9z1ArqracO9y+g2EafKW1suS3pF0h+012492PxaAWTU6/Z56o5x+d2doe5bT785w+g1cJ4gaCEPUQBiiBsIQNRCGqIEwRA2EIWogDFEDYYgaCEPUQBiiBsIQNRCGqIEwRA2EIWogTGsLD17rbkkrXWwYgCTp0BY/40gNhCFqIAxRA2GIGghD1EAYogbCEDUQhqiBMEQNhCFqIAxRA2GIGghD1EAYogbCEDUQhqiBMEQNhCFqIMzEqG3vs33G9qrtS7aX5zEYgNk0WaPsqqQnquqC7R9JOm/7dFV92PFsAGYw8UhdVV9U1YXx119LWpW0t+vBAMxmqufUtvdLukvS2Q1+tmR7xfbKP1oaDsD0Gkdt+2ZJr0l6vKq++v7Pq+pEVR2qqkN72pwQwFQaRW17t0ZBv1RVr3c7EoDtaPLqtyU9L2m1qp7pfiQA29HkSH1E0iOSjtq+OL7c1/FcAGY08S2tqnpbkucwC4AW8B9lQBiiBsIQNRCGqIEwRA2EIWogDFEDYYgaCEPUQBiiBsIQNRCGqIEwRA2EIWogDFEDYYgaCOOqan+jdvsbxcjQ9izLa3SmqjbcuxypgTBEDYQhaiAMUQNhiBoIQ9RAGKIGwhA1EIaogTBEDYQhaiAMUQNhiBoIQ9RAGKIGwhA1EIaogTATo7Z9o+13bb9v+5Ltp+cxGIDZTFzOyLYl/bCqrtjeLeltSctV9Zctfmdoi+4Mx9D2LMsZdWaz5Yx2NfjFknRlfHX3+DK0hxZw3Wj0nNr2gu2LktYlna6qs51OBWBmjaKuqm+r6qCkRUmHbR/4/m1sL9lesb3S8owApjD1EsG2fyfp31X1+y1uw+l5V4a2Z3lO3ZmZlwi2vcf2LeOvb5J0r6SPWp0OQGsmvlAm6VZJf7S9oNEfgVer6lS3YwGYFZ/QMTRD27OcfneGT+gArhNEDYQhaiAMUQNhiBoIQ9RAGKIGwhA1EIaogTBEDYQhaiAMUQNhiBoIQ9RAGKIGwhA1EIaogTBEDYQhaiAMUQNhiBoIQ9RAGKIGwhA1EIaogTBEDYQhaiAMUQNhiBoIQ9RAGKIGwhA1EIaogTBEDYQhaiBM46htL9h+z/apLgcCsD3THKmXJa12NQiAdjSK2vaipPslPdftOAC2q+mR+llJT0r6brMb2F6yvWJ7pY3BAMxmYtS2j0tar6rzW92uqk5U1aGqOtTadACm1uRIfUTSA7Y/lfSKpKO2X+x0KgAzc1U1v7H9c0m/qarjE27XfKOYztD2rPseIFdVbbh3eZ8aCDPVkbrxRjlSd2doe5YjdWc4UgPXCaIGwhA1EIaogTBEDYQhaiAMUQNhiBoIQ9RAGKIGwhA1EIaogTBEDYQhaiAMUQNhiBoIs6uj7f5T0t9b3uaPx9sdim7m7WbRAfZtd7qa9Seb/aCTlU+6YHtlSCuVDmneIc0qDWvePmbl9BsIQ9RAmCFFfaLvAaY0pHmHNKs0rHnnPutgnlMDaGZIR2oADRA1EGYQUds+Zvtj25dtP9X3PFuxfdL2uu0P+p5lEtv7bJ+xvWr7ku3lvmfajO0bbb9r+/3xrE/3PVMTthdsv2f71Lzuc8dHbXtB0h8k/VLSnZIetn1nv1Nt6QVJx/oeoqGrkp6oqp9KukfSr3fwvv2PpKNV9TNJByUds31PvyM1sixpdZ53uOOjlnRY0uWq+qSqvtHokzcf7HmmTVXVW5K+7HuOJqrqi6q6MP76a40efHv7nWpjNXJlfHX3+LKjX+W1vSjpfknPzfN+hxD1XkmfXXN9TTv0gTdktvdLukvS2Z5H2dT4VPaipHVJp6tqx8469qykJyV9N887HULUG/23847+Cz00tm+W9Jqkx6vqq77n2UxVfVtVByUtSjps+0DPI23K9nFJ61V1ft73PYSo1yTtu+b6oqTPe5olju3dGgX9UlW93vc8TVTVvyT9WTv7tYsjkh6w/alGTxmP2n5xHnc8hKjPSbrd9m22b5D0kKQ3ep4pgm1Lel7SalU90/c8W7G9x/Yt469vknSvpI96HWoLVfXbqlqsqv0aPWb/VFW/msd97/ioq+qqpMckvanRCzmvVtWlfqfanO2XJb0j6Q7ba7Yf7XumLRyR9IhGR5GL48t9fQ+1iVslnbH9V43+0J+uqrm9TTQk/JsoEGbHH6kBTIeogTBEDYQhaiAMUQNhiBoIQ9RAmP8Coa7o5KFYWnEAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(make_cross_image(False).permute(1,2,0));"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def show_image_batch(b, show=show_titled_image, items=9, cols=3, figsize=None, **kwargs):\n",
    "    \"Display batch `b` in a grid of size `items` with `cols` width\"\n",
    "    if items<cols: cols=items\n",
    "    rows = (items+cols-1) // cols\n",
    "    if figsize is None: figsize = (cols*3, rows*3)\n",
    "    fig,axs = plt.subplots(rows, cols, figsize=figsize)\n",
    "    for *o,ax in zip(*to_cpu(b), axs.flatten()): show(o, ax=ax, **kwargs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x216 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_image_batch(([Image.open(TEST_IMAGE_BW),Image.open(TEST_IMAGE)],['bw','color']), items=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Model init"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def requires_grad(m):\n",
    "    \"Check if the first parameter of `m` requires grad or not\"\n",
    "    ps = list(m.parameters())\n",
    "    return ps[0].requires_grad if len(ps)>0 else False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tst = nn.Linear(4,5)\n",
    "assert requires_grad(tst)\n",
    "for p in tst.parameters(): p.requires_grad_(False)\n",
    "assert not requires_grad(tst)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def init_default(m, func=nn.init.kaiming_normal_):\n",
    "    \"Initialize `m` weights with `func` and set `bias` to 0.\"\n",
    "    if func:\n",
    "        if hasattr(m, 'weight'): func(m.weight)\n",
    "        if hasattr(m, 'bias') and hasattr(m.bias, 'data'): m.bias.data.fill_(0.)\n",
    "    return m"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tst = nn.Linear(4,5)\n",
    "tst.weight.data.uniform_(-1,1)\n",
    "tst.bias.data.uniform_(-1,1)\n",
    "tst = init_default(tst, func = lambda x: x.data.fill_(1.))\n",
    "test_eq(tst.weight, torch.ones(5,4))\n",
    "test_eq(tst.bias, torch.zeros(5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def cond_init(m, func):\n",
    "    \"Apply `init_default` to `m` unless it's a batchnorm module\"\n",
    "    if (not isinstance(m, norm_types)) and requires_grad(m): init_default(m, func)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tst = nn.Linear(4,5)\n",
    "tst.weight.data.uniform_(-1,1)\n",
    "tst.bias.data.uniform_(-1,1)\n",
    "cond_init(tst, func = lambda x: x.data.fill_(1.))\n",
    "test_eq(tst.weight, torch.ones(5,4))\n",
    "test_eq(tst.bias, torch.zeros(5))\n",
    "\n",
    "tst = nn.BatchNorm2d(5)\n",
    "init = [tst.weight.clone(), tst.bias.clone()]\n",
    "cond_init(tst, func = lambda x: x.data.fill_(1.))\n",
    "test_eq(tst.weight, init[0])\n",
    "test_eq(tst.bias, init[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def apply_leaf(m, f):\n",
    "    \"Apply `f` to children of `m`.\"\n",
    "    c = m.children()\n",
    "    if isinstance(m, nn.Module): f(m)\n",
    "    for l in c: apply_leaf(l,f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tst = nn.Sequential(nn.Linear(4,5), nn.Sequential(nn.Linear(4,5), nn.Linear(4,5)))\n",
    "apply_leaf(tst, partial(init_default, func=lambda x: x.data.fill_(1.)))\n",
    "for l in [tst[0], *tst[1]]: test_eq(l.weight, torch.ones(5,4))\n",
    "for l in [tst[0], *tst[1]]: test_eq(l.bias,   torch.zeros(5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def apply_init(m, func=nn.init.kaiming_normal_):\n",
    "    \"Initialize all non-batchnorm layers of `m` with `func`.\"\n",
    "    apply_leaf(m, partial(cond_init, func=func))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tst = nn.Sequential(nn.Linear(4,5), nn.Sequential(nn.Linear(4,5), nn.BatchNorm1d(5)))\n",
    "init = [tst[1][1].weight.clone(), tst[1][1].bias.clone()]\n",
    "apply_init(tst, func=lambda x: x.data.fill_(1.))\n",
    "for l in [tst[0], tst[1][0]]: test_eq(l.weight, torch.ones(5,4))\n",
    "for l in [tst[0], tst[1][0]]: test_eq(l.bias,   torch.zeros(5))\n",
    "test_eq(tst[1][1].weight, init[0])\n",
    "test_eq(tst[1][1].bias,   init[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## autograd jit functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def script_use_ctx(f):\n",
    "    \"Decorator: create jit script and pass everything in `ctx.saved_variables to `f`, after `*args`\"\n",
    "    sf = torch.jit.script(f)\n",
    "    def _f(ctx, *args, **kwargs): return sf(*args, *ctx.saved_variables, **kwargs)\n",
    "    return update_wrapper(_f,f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def script_save_ctx(static, *argidx):\n",
    "    \"Decorator: create jit script and save args with indices `argidx` using `ctx.save_for_backward`\"\n",
    "    def _dec(f):\n",
    "        sf = torch.jit.script(f)\n",
    "        def _f(ctx, *args, **kwargs):\n",
    "            if argidx:\n",
    "                save = [args[o] for o in argidx]\n",
    "                ctx.save_for_backward(*save)\n",
    "            if not argidx: args = [ctx]+args\n",
    "            return sf(*args, **kwargs)\n",
    "        if static: _f = staticmethod(_f)\n",
    "        return update_wrapper(_f,f)\n",
    "    return _dec"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def script_fwd(*argidx):\n",
    "    \"Decorator: create static jit script and save args with indices `argidx` using `ctx.save_for_backward`\"\n",
    "    return script_save_ctx(True, *argidx)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def script_bwd(f):\n",
    "    \"Decorator: create static jit script and pass everything in `ctx.saved_variables to `f`, after `*args`\"\n",
    "    return staticmethod(script_use_ctx(f))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def grad_module(cls):\n",
    "    \"Decorator: convert `cls` into an autograd function\"\n",
    "    class _c(nn.Module):\n",
    "        def forward(self, *args, **kwargs): return cls.apply(*args, **kwargs)\n",
    "    return _c"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Export -"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Converted 00_torch_core.ipynb.\n",
      "Converted 01_layers.ipynb.\n",
      "Converted 01a_losses.ipynb.\n",
      "Converted 02_data.load.ipynb.\n",
      "Converted 03_data.core.ipynb.\n",
      "Converted 04_data.external.ipynb.\n",
      "Converted 05_data.transforms.ipynb.\n",
      "Converted 06_data.block.ipynb.\n",
      "Converted 07_vision.core.ipynb.\n",
      "Converted 08_vision.data.ipynb.\n",
      "Converted 09_vision.augment.ipynb.\n",
      "Converted 09b_vision.utils.ipynb.\n",
      "Converted 09c_vision.widgets.ipynb.\n",
      "Converted 10_tutorial.pets.ipynb.\n",
      "Converted 10b_tutorial.albumentations.ipynb.\n",
      "Converted 11_vision.models.xresnet.ipynb.\n",
      "Converted 12_optimizer.ipynb.\n",
      "Converted 13_callback.core.ipynb.\n",
      "Converted 13a_learner.ipynb.\n",
      "Converted 13b_metrics.ipynb.\n",
      "Converted 14_callback.schedule.ipynb.\n",
      "Converted 14a_callback.data.ipynb.\n",
      "Converted 15_callback.hook.ipynb.\n",
      "Converted 15a_vision.models.unet.ipynb.\n",
      "Converted 16_callback.progress.ipynb.\n",
      "Converted 17_callback.tracker.ipynb.\n",
      "Converted 18_callback.fp16.ipynb.\n",
      "Converted 18a_callback.training.ipynb.\n",
      "Converted 18b_callback.preds.ipynb.\n",
      "Converted 19_callback.mixup.ipynb.\n",
      "Converted 20_interpret.ipynb.\n",
      "Converted 20a_distributed.ipynb.\n",
      "Converted 21_vision.learner.ipynb.\n",
      "Converted 22_tutorial.imagenette.ipynb.\n",
      "Converted 23_tutorial.vision.ipynb.\n",
      "Converted 24_tutorial.siamese.ipynb.\n",
      "Converted 24_vision.gan.ipynb.\n",
      "Converted 30_text.core.ipynb.\n",
      "Converted 31_text.data.ipynb.\n",
      "Converted 32_text.models.awdlstm.ipynb.\n",
      "Converted 33_text.models.core.ipynb.\n",
      "Converted 34_callback.rnn.ipynb.\n",
      "Converted 35_tutorial.wikitext.ipynb.\n",
      "Converted 36_text.models.qrnn.ipynb.\n",
      "Converted 37_text.learner.ipynb.\n",
      "Converted 38_tutorial.text.ipynb.\n",
      "Converted 39_tutorial.transformers.ipynb.\n",
      "Converted 40_tabular.core.ipynb.\n",
      "Converted 41_tabular.data.ipynb.\n",
      "Converted 42_tabular.model.ipynb.\n",
      "Converted 43_tabular.learner.ipynb.\n",
      "Converted 44_tutorial.tabular.ipynb.\n",
      "Converted 45_collab.ipynb.\n",
      "Converted 46_tutorial.collab.ipynb.\n",
      "Converted 50_tutorial.datablock.ipynb.\n",
      "Converted 60_medical.imaging.ipynb.\n",
      "Converted 61_tutorial.medical_imaging.ipynb.\n",
      "Converted 65_medical.text.ipynb.\n",
      "Converted 70_callback.wandb.ipynb.\n",
      "Converted 71_callback.tensorboard.ipynb.\n",
      "Converted 72_callback.neptune.ipynb.\n",
      "Converted 73_callback.captum.ipynb.\n",
      "Converted 74_callback.cutmix.ipynb.\n",
      "Converted 97_test_utils.ipynb.\n",
      "Converted 99_pytorch_doc.ipynb.\n",
      "Converted dev-setup.ipynb.\n",
      "Converted index.ipynb.\n",
      "Converted quick_start.ipynb.\n",
      "Converted tutorial.ipynb.\n"
     ]
    }
   ],
   "source": [
    "#hide\n",
    "from nbdev.export import notebook2script\n",
    "notebook2script()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "jupytext": {
   "split_at_heading": true
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
